Building the IDE for Mac OS X

Hi,
I checked out the source from svn last night wanting to apply patches to the build system so I can run on the ATmega328 that I bought the other day. I saw that the tools directory is just zipped up in the repository.

I'm wondering if there is a script from someone in how to build a new tools directory or should I just use the scripts I found on avrfreaks? If there isn't a script some where that does this properly (eg, building it universal) I will get to it and submit it.

Thanks,
Greg

You shouldn't need to rebuild the tools, just patch the core (in hardware/cores/arduino). You can actually just download the distribution, since it compiles the core from source every time you compile or upload a sketch.

Thanks mellis. I didn't realise I didn't need to build the tools. i had seen a post sometime ago that had said a newer version of gcc was required.

I have added in the changes for the ATmega328P and put it up on a server as a diff if you would like to include it into svn.

I am however having a problem using the chip in that when I try to load a simple hello world test, it just prints out jibberish.

void setup()
{ 
  Serial.begin(9600);
  Serial.println("Hello ATmega328P");
}

void loop()
{
  
}

And this is the output

HHHHHHHHHÈHeHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

Any info is greatly appreciated.

Thanks,
Greg

Did you modify the serial code at all? If so, can you post it? If not, you might have to.

Yes, I added the defines for the AVR_ATmega328P_

The diff in the above post is against the svn repo.

/*
  wiring_serial.c - serial functions.
  Part of Arduino - http://www.arduino.cc/

  Copyright (c) 2005-2006 David A. Mellis

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library 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
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General
  Public License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  Boston, MA  02111-1307  USA

  $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
*/

#include "wiring_private.h"

// Define constants and variables for buffering incoming serial data.  We're
// using a ring buffer (I think), in which rx_buffer_head is the index of the
// location to which to write the next incoming character and rx_buffer_tail
// is the index of the location from which to read.
#define RX_BUFFER_SIZE 128

unsigned char rx_buffer[RX_BUFFER_SIZE];

int rx_buffer_head = 0;
int rx_buffer_tail = 0;

void beginSerial(long baud)
{
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
      UBRR0H = ((F_CPU / 16 + baud / 2) / baud - 1) >> 8;
      UBRR0L = ((F_CPU / 16 + baud / 2) / baud - 1);
      
      // enable rx and tx
      sbi(UCSR0B, RXEN0);
      sbi(UCSR0B, TXEN0);
      
      // enable interrupt on complete reception of a byte
      sbi(UCSR0B, RXCIE0);
#else
      UBRRH = ((F_CPU / 16 + baud / 2) / baud - 1) >> 8;
      UBRRL = ((F_CPU / 16 + baud / 2) / baud - 1);
      
      // enable rx and tx
      sbi(UCSRB, RXEN);
      sbi(UCSRB, TXEN);
      
      // enable interrupt on complete reception of a byte
      sbi(UCSRB, RXCIE);
#endif
      
      // defaults to 8-bit, no parity, 1 stop bit
}

void serialWrite(unsigned char c)
{
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
      while (!(UCSR0A & (1 << UDRE0)))
            ;

      UDR0 = c;
#else
      while (!(UCSRA & (1 << UDRE)))
            ;

      UDR = c;
#endif
}

int serialAvailable()
{
      return (RX_BUFFER_SIZE + rx_buffer_head - rx_buffer_tail) % RX_BUFFER_SIZE;
}

int serialRead()
{
      // if the head isn't ahead of the tail, we don't have any characters
      if (rx_buffer_head == rx_buffer_tail) {
            return -1;
      } else {
            unsigned char c = rx_buffer[rx_buffer_tail];
            rx_buffer_tail = (rx_buffer_tail + 1) % RX_BUFFER_SIZE;
            return c;
      }
}

void serialFlush()
{
      // don't reverse this or there may be problems if the RX interrupt
      // occurs after reading the value of rx_buffer_head but before writing
      // the value to rx_buffer_tail; the previous value of rx_buffer_head
      // may be written to rx_buffer_tail, making it appear as if the buffer
      // were full, not empty.
      rx_buffer_head = rx_buffer_tail;
}

#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
SIGNAL(SIG_USART_RECV)
#else
SIGNAL(SIG_UART_RECV)
#endif
{
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
      unsigned char c = UDR0;
#else
      unsigned char c = UDR;
#endif

      int i = (rx_buffer_head + 1) % RX_BUFFER_SIZE;

      // if we should be storing the received character into the location
      // just before the tail (meaning that the head would advance to the
      // current location of the tail), we're about to overflow the buffer
      // and so we don't write the character or advance the head.
      if (i != rx_buffer_tail) {
            rx_buffer[rx_buffer_head] = c;
            rx_buffer_head = i;
      }
}

Pardon me if this is off base, but should F_CPU be changed to 20Mhz for the 328p? The output looks somewhat like what you get when the serial tx/rx clocks are mismatched.

Hi Mikal,
I'm not sure if that is correct. The crystal on the diecimila is 16MHz. The part number of the 328P is ATMEGA328P-20PU which is a 20MHz piece. Does this mismatch affect anything even if I keep the F_CPU at 16MHz?

Thanks,
Greg

The F_CPU constant should correspond to the crystal on the board (16 MHz), not the maximum possible speed for the chip (20 MHz). The output makes it look like you're not checking or using the right registers, and so the same character is getting sent over and over again. I don't think it's a baud rate problem.

I'm not too sure where to look for this. In the serialWrite() function I have this:

void serialWrite(unsigned char c)
{
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
      while (!(UCSR0A & (1 << UDRE0)))
            ;

      UDR0 = c;
#else

I looked up in the datasheets for both the processors and from what I could understand, the layout of the UCSR0A is the same.

Can you point me in the right direction please.

Thanks,
Greg

Hmm, what output do you get if you try a different string in Serial.print()? Does the datasheet say anything about having to clear UDR0? Is there any interrupt driven serial communication that needs to be disabled?

I normally just get what looks to be the first character in whatever I try to send for the first time. Here is the relevant section from the manual.

The USART Transmit Data Buffer Register and USART Receive Data Buffer Registers share the
same I/O address referred to as USART Data Register or UDRn. The Transmit Data Buffer Reg-
ister (TXB) will be the destination for data written to the UDRn Register location. Reading the
UDRn Register location will return the contents of the Receive Data Buffer Register (RXB).
For 5-, 6-, or 7-bit characters the upper unused bits will be ignored by the Transmitter and set to
zero by the Receiver.
The transmit buffer can only be written when the UDREn Flag in the UCSRnA Register is set.
Data written to UDRn when the UDREn Flag is not set, will be ignored by the USART Transmit-
ter. When data is written to the transmit buffer, and the Transmitter is enabled, the Transmitter
will load the data into the Transmit Shift Register when the Shift Register is empty. Then the
data will be serially transmitted on the TxDn pin.
The receive buffer consists of a two level FIFO. The FIFO will change its state whenever the
receive buffer is accessed. Due to this behavior of the receive buffer, do not use Read-Modify-
Write instructions (SBI and CBI) on this location. Be careful when using bit test instructions
(SBIC and SBIS), since these also will change the state of the FIFO.

looking at this bit of code

while (!(UCSR0A & (1 << UDRE0)))
            ;

      UDR0 = c;

seems to look right in that it waits until the bit is set.

I am not a hardware guy (only software) and am just learning this stuff at the moment so if you you keep pointing my ship north is greatly appreciated.

thanks,
greg

What if you just try printing a single character?

Printing 1 character will continually print out the same character.

I'm baffled, anyone else have any ideas? Also, have you seen: http://spiffie.org/know/arduino_328/?

If you are up to it, try my tutorial on getting 0012 working in MacOSX with the 328P:

http://ladyada.net/forums/viewtopic.php?f=25&t=7668

Many thanks to SolidSilver for his guide on getting this working in Linux.

I'm happy to report that I am compiling/uploading .hex from the Arduino-0012 environment to my 328P in my Duemilanove.