/*
  SD card basic file example
 
 This example shows how to create and destroy an SD card file 	
 The circuit:
 * SD card attached to SPI bus as follows:
	Refer to "libraries/SdFat/Sd2Card_config.h" 
 
 
 created   Nov 2010
 by David A. Mellis
 updated 2 Dec 2010
 by Tom Igoe
 modified for Maple(STM32 micros)/libmaple
 17 Mar 2012
 by dinau	  
 
 This example code is in the public domain.
 	 
 */
#include <Ethernet.h>
#include <SD.h>

// #define Serial  Serial1
// #define Serial  SerialUSB
#define LED_ON        digitalWrite(BOARD_LED_PIN, HIGH)
#define LED_OFF       digitalWrite(BOARD_LED_PIN, LOW)
#define pin_SD_nMedia  (D27)
#define is_SDmedia (LOW==digitalRead(pin_SD_nMedia))
static int error_flag=0;
static int inByte;

File root;

// change this to match your SD shield or module;
//const int chipSelect = SD_CHIP_SELECT_PIN;
const int chipSelect = 25;

void printDirectory(File dir, int numTabs); /* Forward definition */

#define ADDR_GPIOA_BASE (0x40010800)
#define ADDR_GPIOB_BASE (0x40010C00)
#define ADDR_AFIO_BASE  (0x40010000)
#define ADDR_SPI1_BASE  (0x40013000)
#define ADDR_SPI2_BASE  (0x40003800)
#define ADDR_SPI3_BASE  (0x40003c00)
#define ADDR_I2C1_BASE  (0x40005400)
#define ADDR_I2C2_BASE  (0x40005800)

void dumpreg(uint32_t addr, uint32_t sz){
uint32_t i;
    for(i=0;i<sz;i++){
      if(((addr & 15)==0) || i==0){
        Serial.print("\r\n");
        Serial.print(addr, 16);
        Serial.print(": ");
      };
      Serial.print(*(uint8_t *)addr, 16);
      addr +=1;
      Serial.print(" ");
    };
}
void dumpregs(void){
    Serial.print("\r\nGPIO_A:");
    dumpreg(ADDR_GPIOA_BASE     ,8); // CR
    Serial.print("\r\nGPIO_B:");
    dumpreg(ADDR_GPIOB_BASE     ,8); // CR
    Serial.print("\r\nAFIO_A:");
    dumpreg(ADDR_AFIO_BASE     ,8); // AFIO_regs
    dumpreg(ADDR_AFIO_BASE+0x08,2); // AFIO_EXTICR1
    dumpreg(ADDR_AFIO_BASE+0x0c,2); // AFIO_EXTICR2
    dumpreg(ADDR_AFIO_BASE+0x10,2); // AFIO_EXTICR3
    dumpreg(ADDR_AFIO_BASE+0x14,2); // AFIO_EXTICR4
    Serial.print("\r\nSPI2:");
    dumpreg(ADDR_SPI2_BASE+0x00 ,2); // SPI_CR1
    dumpreg(ADDR_SPI2_BASE+0x04 ,1); // SPI_CR2
    Serial.print("\r\n");
}


void setup()
{
  pinMode(BOARD_LED_PIN,   OUTPUT);
  pinMode(BOARD_BUTTON_PIN, INPUT);
  pinMode(pin_SD_nMedia, INPUT_PULLUP);

  LED_ON;
  Serial.begin(BPS_115200);
  PgmPrintln("Type any character to start");
  while (!Serial.available() && !isButtonPressed());

  Serial.print("Initializing SD card...");
  pinMode(chipSelect, OUTPUT);

  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    error_flag=1;
    return;
  }
  Serial.println("initialization done.");

  root = SD.open("/");
  
  printDirectory(root, 0);
  
  Serial.println("done!");
}

void loop()
{
  int bltime;
  LED_ON;
  if(is_SDmedia){
    bltime=2000;
  }else{
    bltime=1000;
  };

  delay(2);
  LED_OFF;
  if(error_flag){
    delay(330);
    LED_ON;
    delay(2);
    LED_OFF;
    delay(330);
    LED_ON;
    delay(2);
    LED_OFF;
    delay(bltime/2);
  }else{
    delay(bltime);
  };
  while(Serial.available()) {
     inByte = Serial.read();
     Serial.print(inByte, BYTE);
     dumpregs(); 
  };
  if(inByte){
    togglePin(chipSelect);
    inByte= 0;
  };
}

void printDirectory(File dir, int numTabs) {
   while(true) {
     
     File entry =  dir.openNextFile();
     if (! entry) {
       // no more files
       //Serial.println("**nomorefiles**");
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       Serial.print('\t');
     }
     Serial.print(entry.name());
     if (entry.isDirectory()) {
       Serial.println("/");
       printDirectory(entry, numTabs+1);
     } else {
       // files have sizes, directories do not
       Serial.print("\t\t");
       Serial.println(entry.size(), DEC);
     }
     entry.close();
   }
}

