0

I am having an issue using a MAX 3421 EE based Arduino USB Host shield and an SD card shield. From my understanding, they should both function as long as they are using different CS/SS pins and only one is active at a time. I have connected the SD card CS pin to pin 4. I am trying to write a program that reads an ACM terminal and writes that data to a file on the SD card (see code below). When the SD card is not powered the USB host shield reads the ACM and prints it to serial fine. However, immediately when I connect the SD card shield power, it starts printing "ACM not ready." On a reset, it prints "OSCOKIRQ failed to assert."

Troubleshooting steps I have already tried:

  • External power source.
  • Removing SD card from the reader.
  • Commenting out all SD Card code.
  • Disconnecting USB Device (to see if initialization still works)

None of these steps have helped solve the USB initialization issue.

My code:

//Lots of Code from https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/acm/acm_terminal/acm_terminal.ino
#include <cdcacm.h>
#include <usbhub.h>

#include "pgmstrings.h"

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif

#include <SPI.h>
//#include <SD.h>

//https://github.com/felis/USB_Host_Shield_2.0.git
class ACMAsyncOper : public CDCAsyncOper{
public:
    uint8_t OnInit(ACM *pacm);
};

uint8_t ACMAsyncOper::OnInit(ACM *pacm){
    uint8_t rcode;
    // Set DTR = 1 RTS=1
    rcode = pacm->SetControlLineState(3);

    if (rcode)
    {
        ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode);
        return rcode;
    }

    LINE_CODING lc;
    lc.dwDTERate    = 115200;
    lc.bCharFormat  = 0;
    lc.bParityType  = 0;
    lc.bDataBits    = 8;

    rcode = pacm->SetLineCoding(&lc);

    if (rcode)
        ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);

    return rcode;
}

const int USBChipSelect = 10;
USB     Usb;
//USBHub     Hub(&Usb);
ACMAsyncOper  AsyncOper;
ACM           Acm(&Usb, &AsyncOper);

const int SDChipSelect = 4;
/*
const int maxLog = 10000;
volatile int logged = 0;
volatile long name = 0;
*/
void setup()
{
    Serial.begin(115200);
    Serial.println("Start");

    pinMode(USBChipSelect, OUTPUT); // Sets USB CS pin output
    pinMode(SDChipSelect, OUTPUT); //Sets SD CS pin output
    digitalWrite(SDChipSelect,HIGH);
    digitalWrite(USBChipSelect,HIGH);

    USBActive();

    if (Usb.Init() == -1){
    Serial.println("OSCOKIRQ failed to assert");
  }

    delay(500);
}

void loop(){
    String toWrite = "Error";


    toWrite = readACM();
    Serial.println(toWrite);

    if(logged>=maxLog){
        logged = 0;
        name++;
    }
    /*
    SD.begin(SDChipSelect);
    File dataFile = SD.open(String(name), FILE_WRITE);
    if(dataFile){
        dataFile.println(toWrite);
        dataFile.close();
    }*/
    delay(100);
}

//Activates USB and Deactivates SD
void USBActive(){
    digitalWrite(SDChipSelect,HIGH);
    digitalWrite(USBChipSelect,LOW);
}

//Activates SD and Deactiavates USB
void SDActive(){
    digitalWrite(USBChipSelect,true);
    digitalWrite(SDChipSelect,false);
}

String readACM(){
  Usb.Task();

  if( Acm.isReady()) {
       uint8_t rcode;

        /* reading the phone */
        /* buffer size must be greater or equal to max.packet size */
        /* it it set to 64 (largest possible max.packet size) here, can be tuned down
        for particular endpoint */
        uint8_t  buf[64];
        uint16_t rcvd = 64;
        rcode = Acm.RcvData(&rcvd, buf);
         if (rcode && rcode != hrNAK)
            ErrorMessage<uint8_t>(PSTR("Ret"), rcode);

        if( rcvd ) { //more than zero bytes received
            char rcvdData[rcvd];
            for(uint16_t i=0; i < rcvd; i++ ) {
                rcvdData[i] = (char)buf[i]; //printing on the screen
            }
            return String(rcvdData);
        }
    }
    return String("ACM Not Ready");
}

Thanks in Advance.

  • As I remember SD cards don't behave well on the SPI bus. They are blocking all other devices. – chrisl May 21 at 19:41
  • If they block all other SPI devices why do they still have a CS line? Isn't the CS line to select which device on the SPI bus to use. – Abe Zukor May 21 at 19:55
  • Found this question, which suggests, that the problem lies with the cheap sd card modules, not with the cards themselves. I guess you use one of these modules, since you have to convert the 5V level of the Arduino to the 3.3V of the SD card. – chrisl May 21 at 20:18
  • Ok, I thought the SD card module was a bit too cheap but it worked fine on its own. Any suggestions for an SD card module (preferably MicroSD) that does this properly? – Abe Zukor May 21 at 20:24
  • the Adafruit SD adapter is good – Juraj May 22 at 5:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.