ATMEL Mega1284P evaluation board avalible

Hmm, looks like it needs to an int, compiles now.
Thanks for the idea to look at that.
Pressing on ...

Woohoo, I2C & RTC Work, as does Square Wave Output (demonstrated via flashing LED).

/*
Test of RTC DS1307 via I2C.
 Counts 
 Seconds, 
 Minutes, 
 Hours, 
 Date of the Month, 
 Month, 
 Day of the week, and 
 Year with Leap-Year
 
 56 bytes battery backed RAM
 Square Wave Output, can connect to INT2/D6 or PD7
 */

#include <Wire.h>

//variables
byte seconds_address = 0x00;
byte seconds; // bit 7 = Clock Halt, Enabled = 0, Halt = 1
// bits 6-5-3 = tens of seconds 0-6,  bits 3-2-1-0 = units of seconds, 0-9
byte minutes_address = 0x01;
byte minutes;  // bits 6-5-4 = tens of minutes, bits 3-2-1-0 = units of minutes
byte hours_address = 0x02; 
byte hours;  // 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
// bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
// bit 4 =  lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)
byte day_week_address = 0x03; 
byte day_week = 0; // range 01-07
byte date_month_address = 0x04;
byte date_month = 0; // range 01-31
byte month_address = 0x05;
byte month = 0; // range 01-12
byte year_address = 0x06;
int year = 0; // upper byte 0-9, lower byte 0-9
byte square_address = 0x07;
byte sqwe = 0;  // square wave enable
// Out-0-0-Sqwe-0-0-RS1-RS0
// Out, Sqwe = 0/0 - Square wave output = 0
// Out, Sqwe = 1/0 - Square wave output = 1
// Out, Sqwe = 0/1 or 1/1 - Square wave output per RS1/RS0
// RS1/RS0 = 00 = 1 Hz
// RS1/RSo = 01 = 4 KHz
// RS1/RS0 = 10 = 8 KHz
// RS1/RS0 = 11 = 32 KHz
byte RTC_ram_address = 0x08; //range = 08-63, 0x08-0x3F

int RTC_address = 0x68; // 1101 000 

byte incomingCommand = 0;
byte RTC_write_command = 0;
byte RTC_read_command = 0;
byte RTC_ram_command = 0;
// use F0xx, F1xx,F2xx, F3xx, F4xx, F5xx, F6xx, F7xx
// to send one register write commands
// use E0xx to read registers back
// use C0xx to read RAM back
byte incomingRegister = 0;
byte RTC_register = 0;
byte incomingData = 0;
byte new_data = 0;
byte outgoingData = 0;
int delay_time = 100;

unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long duration = 5000;

void setup() {
  Wire.begin(); // no address, we are master
  Serial1.begin (57600);  
  Serial1.flush();
  currentMillis = millis();  
}

void loop() {

  if (Serial1.available() >1){
    incomingCommand = Serial1.read();
    //incomingRegister = Serial.read();
    incomingData = Serial1.read();
    Serial1.print ("command ");
    Serial1.println (incomingCommand & 0xF0, HEX);
    Serial1.print ("register ");
    Serial1.println(incomingCommand & 0x0F, HEX);
    Serial1.print ("data ");
    Serial1.println (incomingData, HEX);
  }
  // *******************************************
  RTC_write_command = incomingCommand & 0xF0;  // mask off high byte
  if (RTC_write_command == 0xF0){  // e033check for Write command
    RTC_register = incomingCommand & 0x0F;  // mask off low btye
    incomingCommand = 0;
    new_data = incomingData;
    Serial1.print (" Sending a command ");
    switch (RTC_register){
    case 0: // write seconds
        Serial1.println ("Seconds ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(seconds_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
      delay (delay_time);
      break;
    case 1: // write minutes
    Serial1.print ("Minutes ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(minutes_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
      delay (delay_time);
      break;
    case 2: // write hours
        Serial1.print ("Hours ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(hours_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case 3: // write day
        Serial1.print ("Day ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(day_week_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case 4: // write date of month
        Serial1.print ("Day of Month ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(date_month_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case 5: // write month
        Serial1.print ("Month ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(month_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case 6: // write year
        Serial1.print ("Year ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(year_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case 7: // write square wave
        Serial1.print ("Square Wave ");
    Serial1.println (RTC_register, HEX);
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(square_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case 8: // write RAM
        Serial1.print ("RAM ");
    Serial1.println (RTC_register, HEX);
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(RTC_ram_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
      // all others,do nothing
      Serial.println ("Invalid command ");
    }  // end Switch
  } // end if command == F
  // ************************************

  currentMillis = millis();
  if ( (currentMillis - previousMillis) >= duration){
    previousMillis = currentMillis;  
    // Reset the register pointer  
    Wire.beginTransmission(RTC_address);  
    Wire.send(0x00);  
    Wire.endTransmission();   

    Wire.requestFrom(RTC_address, 8 );  
    seconds = Wire.receive();  
    minutes = Wire.receive();  
    hours = Wire.receive();  
    day_week = Wire.receive();  
    date_month = Wire.receive();  
    month = Wire.receive();  
    year = Wire.receive();  
    sqwe = Wire.receive();

    // Seconds 
    // bit 7 = Clock Halt, Enabled = 0, Halt = 1
    // bits 6-5-3 = tens of seconds 0-6,  bits 3-2-1-0 = units of seconds, 0-9 

    // Hours
    // 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
    // bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
    // bit 4 =  lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)

    Serial1.print ("Hrs " );
    Serial1.print (hours, HEX);
    Serial1.print (" Mins ");
    Serial1.print (minutes, HEX);
    Serial1.print (" Secs ");
    Serial1.print (seconds, HEX);
    Serial1.print (" Day ");
    Serial1.print (day_week, HEX);
    Serial1.print (" Date ");
    Serial1.print (date_month, HEX);
    Serial1.print (" Month ");
    Serial1.print (month, HEX);
    Serial1.print (" Year 20");
    Serial1.print (year, HEX);
    Serial1.print (" Square Wave ");
    Serial1.println (sqwe, HEX);

  }
}

Moniter output:

Hrs 1 Mins 54 Secs 27 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Hrs 1 Mins 54 Secs 32 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Hrs 1 Mins 54 Secs 37 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Hrs 1 Mins 54 Secs 42 Day 4 Date 27 Month 7 Year 2011 Square Wave 10
Hrs 1 Mins 54 Secs 47 Day 4 Date 27 Month 7 Year 2011 Square Wave 10

Tomorrow, SPI ... And see if the clock is running fast ...

@pito, was that cap on XTAL1 of the RTC suppose to make it go faster, slower, anything?
Has a 22pF cap now.

..as I wrote:

  1. do not deploy any cap
  2. if the clock goes fast then start to add a cap. The bigger the cap the slower the clock
  3. if the clock goes slow (and none cap there) exchange the xtal
  4. the cap would be typically 0 .. 15pf, but it depends on the xtal used
    P.

PS: as far as I can remeber the clock system on arduino works in the way the arduino's internal clock is used (there is a Timer.c for sys time) and the internal clock is synchronised by the external RTC in a specific regular intervals (to be set, e.g. 300sec). The sdfat lib rely on the internal clock..
...
setSyncProvider(RTC.get); // the function to get the time from the actual RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
setSyncInterval(300); // set the number of seconds between re-sync of time
SdFile::dateTimeCallback(dateTime);
...
You have to link the time through a dateTime() callback function in order to use it with FAT.

@ two sdcards to run in parallel: frankly, not sure the arduino sdfat is prepared for two sdcards connected (two cards selects is not enough, though). Imagine you have two cards, opened, one for read, the second for write. You need 2 buffers, and the sdfat driver in basically two different states (two different instances of the sdfat driver).. It might be a challenge.. :cold_sweat:

pito:
@ two sdcards to run in parallel: frankly, not sure the arduino sdfat is prepared for two sdcards connected (two cards selects is not enough, though). Imagine you have two cards, opened, one for read, the second for write. You need 2 buffers, and the sdfat driver in basically two different states (two different instances of the sdfat driver).. It might be a challenge.. :cold_sweat:

My understanding was that the main idea was to be able to support either card -- one might not populate both card holders, but this gave the user the choice of which style. And I gather that given the wealth of pins, it made sense for the hardware to support both simultaneously, even if it's a "future" on the software side.

.. yes, you are right.. I am thinking about the future (as I passed the exercise with one sdcard already..)- how to run both cards simultanously.. maybe the latest sdfat supports more than one card opened.. if not, maybe chan's fatfs..p.

The current version of SdFat can't support multiple SD cards. You could have cards in both sockets and access one at a time by closing all files, and calling sd.init(speed, chipSelect) to switch cards.

I have a development version that mostly works with multiple cards. You can have files open on all cards at the same time.

It uses multiple instances of the SdFat class.

This is what a program that copies a file from one card to another looks like:

#include <SdFat.h>
#include <SdFatUtil.h>
SdFat sd1;
SdFat sd2;
uint8_t buf[100];
void setup() {
  Serial.begin(9600);
  PgmPrintln("type any character to start");
  while (!Serial.available());
  if (!sd1.init(SPI_FULL_SPEED, 10)) {
    PgmPrintln("Sd1:");
    sd1.initErrorHalt();
  }
  if (!sd2.init(SPI_FULL_SPEED, 9)) {
    PgmPrintln("Sd2:");
    sd2.initErrorHalt();
  }
  PgmPrintln("FreeRam: ");
  Serial.println(FreeRam());
  sd1.ls();
  PgmPrintln("-------------");
  sd2.ls();
  SdFile file1;
  sd1.chdir();
  if (!file1.open("TEST.BIN", O_READ)) {
    sd1.errorHalt("file1");
  }
  sd2.chdir();
  SdFile file2;
  if (!file2.open("COPY.BIN", O_WRITE | O_CREAT | O_TRUNC)) {
    sd2.errorHalt("file2");
  }
  uint32_t t = millis();
  while (1) {
    int n = file1.read(buf, sizeof(buf));
    if (n == 0) break;
    if (n < 0) sd1.errorHalt("read1");
    if (file2.write(buf, n) != n) sd2.errorHalt("write2");
  }
  t = millis() - t;
  PgmPrintln("File size: ");
  Serial.println(file2.fileSize());
  PgmPrintln("Copy time: ");
  Serial.print(t);
  PgmPrintln(" millis");
  file2.close();
}
void loop() {}

I may post a beta in a week or two.

..great news!!.. there is a lot of space in the 1284p to run many instances of it.. thanks! p.
PS: will the new sdfat support 2 cards run on the same SPI? Or, do we need a separate SPI for each card??

The SD card socket on the top of the board has a seperate Slave Select from the uSD card socket on the bottom of the board.
(If a uSD card socket is mounted on the of the board in place of a SD card socket, the bottom uSD card socket can not be installed, they both use the same physical alignment hole.)

(If a uSD card socket is mounted on the of the board in place of a SD card socket, the uSD card socket can not be installed, they both use the same physical alignment hole.)

I'm sure you can get away with cutting off the alignment pin and soldering it carefully...

SdFat expects all cards to be on the same SPI bus. On the 1284P this is PB4 - PB7.

Each card has a separate chip select.

..this is a good message for us.. :slight_smile:

"I'm sure you can get away with cutting off the alignment pin and soldering it carefully..."

Probably, is just 2 little plastic nubs - but they also have the same SS signal, that'd be a little trickier (doable, but trickier) to cut the trace and add a jumper wire.
I will have the top sockets share the same SS signal next time.
I suppose I could have an SD socket as an option for the bottom as well.

I am running the SDFat Quickstart file.

It starts, I get the messages, I enter my pin #, then nothing happens.
Should I be doing something else?

SD chip select is the key hardware option.
Common values are:
Arduino Ethernet shield, pin 4
Sparkfun SD shield, pin 8
Adafruit SD shields and modules, pin 10
The default chip select pin number is pin 4

Enter the chip select pin number: 30

..you have to add to the sd2pinmap.h (in the sdfat lib folder) the 1284p definitions..

...for example

//------------------------------------------------------------------------------
#elif defined(AVR_ATmega1284P)

// Two Wire (aka I2C) ports
uint8_t const SDA_PIN = 17;
uint8_t const SCL_PIN = 16;

// SPI port
uint8_t const SS_PIN = 4; //12;
uint8_t const MOSI_PIN = 5; //13;
uint8_t const MISO_PIN = 6; //14;
uint8_t const SCK_PIN = 7; //15;

static const pin_map_t digitalPinMap[] = {
{&DDRA, &PINA, &PORTA, 0}, // A0 0 ADC0
{&DDRA, &PINA,...................

@crossroads: maybe off the topic:

  1. which microsdcard socket you use (the TFP09-12-2B ?)
  2. the two positioning holes are large enough ?
    (looking for the eagle lib part so asking whether it worked fine..).P.

pito,
Thanks for #351, fat16lib wrote back to me also that sd2pinmap.h would need to change. Will check that out when I get home. Looks like I need to mimic the contents of what I put in pins_arduino.c (all 32 IO pins ? Or just the 4 pins used for SPI ?)

uSD connecter, I used the Molex connecter that dipmicro sells, they have a library symbol for it also.

"MicroSD/TransFlash push/push connector. This connector is designed for SMT PCB mount, extensive use without mounting may loosen the pins. The free Eagle library provided by Roman Vaughan from Auckland, New Zealand is with his permission available here. " (actual link shows up on page)

Mounted nicely, even tho it was hand soldered (by my wife, very nice touch). Haven't tried it with a card yet.

..put there everything as you may see with the other mcu's there..
the sdcard shall then work when connected properly.. those demos wait on "type any character to start" so you have to push the button :slight_smile:
Run sdinfo.pde and you may see then what is your card like. In the older sdfat versions there is sdfatbench.pde - it measures the r/w speeds.. I would recommend you to have a look on the examples from older versions of sdfat as well..

Thanks for sdcard socket info, I've seen tons of those sockets on ebay and it seems it is the one I'll order.
P.

Thanks pito, am looking forward to checking that out after work.
Robert