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.