/** * Read part of a 512 byte block from a SD card. * * \param[in] block Logical block to be read. * \param[in] offset Number of bytes to skip at start of block * \param[out] dst Pointer to the location that will receive the data. * \param[in] count Number of bytes to read * \return The value one, true, is returned for success and * the value zero, false, is returned for failure. */ uint8_t sdReadData(uint32_t block, uint16_t offset, uint8_t *dst, uint16_t count) { uint16_t i; if (count == 0) return 1; if ((count + offset) > 512) { return 0; } if (!inBlock_ || block != block_ || offset < offset_) { block_ = block; // use address if not SDHC card if (sdType()!= SD_CARD_TYPE_SDHC) block <<= 9; if (sdCardCommand(CMD17, block)) { error1(SD_CARD_ERROR_CMD17); return 0; } if (!sdWaitStartBlock()) { return 0; } offset_ = 0; inBlock_ = 1; } // start first SPI transfer SPDR = 0XFF; // skip data before offset for (;offset_ < offset; offset_++) { while(!(SPSR & (1 << SPIF))); SPDR = 0XFF; } // transfer data uint16_t n = count - 1; for (i = 0; i < n; i++) { while(!(SPSR & (1 << SPIF))); dst[i] = SPDR; SPDR = 0XFF; } // wait for last byte while(!(SPSR & (1 << SPIF))); dst[n] = SPDR; offset_ += count; if (!partialBlockRead_ || offset_ >= 512) sdReadEnd(); return 1; }
/** Simple cone using dimensions to be used to define cone composed of 1 single material @author Clement Helsens **/ static DD4hep::Geometry::Ref_t createSimpleCone(DD4hep::Geometry::LCDD& lcdd, xml_h e, DD4hep::Geometry::SensitiveDetector sensDet) { xml_det_t x_det = e; std::string name = x_det.nameStr(); DD4hep::Geometry::DetElement coneDet(name, x_det.id()); DD4hep::Geometry::Volume experimentalHall = lcdd.pickMotherVolume(coneDet); xml_comp_t coneDim(x_det.child(_U(dimensions))); DD4hep::Geometry::Cone cone(coneDim.dz(), coneDim.rmin1(), coneDim.rmax1(), coneDim.rmin2(), coneDim.rmax2()); DD4hep::Geometry::Volume coneVol(x_det.nameStr() + "_SimpleCone", cone, lcdd.material(coneDim.materialStr())); if (x_det.isSensitive()) { DD4hep::XML::Dimension sdType(x_det.child(_U(sensitive))); coneVol.setSensitiveDetector(sensDet); sensDet.setType(sdType.typeStr()); } DD4hep::Geometry::PlacedVolume conePhys; double zoff = coneDim.z_offset(); if (fabs(zoff) > 0.000000000001) { double reflectionAngle = 0.; if (coneDim.hasAttr(_Unicode(reflect))) { if (coneDim.reflect()) { reflectionAngle = M_PI; } } DD4hep::Geometry::Position trans(0., 0., zoff); conePhys = experimentalHall.placeVolume(coneVol, DD4hep::Geometry::Transform3D(DD4hep::Geometry::RotationX(reflectionAngle), trans)); } else conePhys = experimentalHall.placeVolume(coneVol); conePhys.addPhysVolID("system", x_det.id()); coneDet.setPlacement(conePhys); coneDet.setVisAttributes(lcdd, x_det.visStr(), coneVol); return coneDet; }
/** * Initialize a SD flash memory card. * * \param[in] slow If \a slow is false (zero) the SPI bus will * be initialize at a speed of 8 Mhz. If \a slow is true (nonzero) * the SPI bus will be initialize a speed of 4 Mhz. This may be helpful * for some SD cards with Version 1.0 of the Adafruit Wave Shield. * * \return The value one, true, is returned for success and * the value zero, false, is returned for failure. * */ uint8_t sdInit(uint8_t slow) { uint8_t r; uint16_t i; uint8_t retry; uint32_t t0=0; //pinMode(SS, OUTPUT); DDRB |= _BV(SS); //digitalWrite(SS, HIGH); PORTB |= _BV(SS); //pinMode(MOSI, OUTPUT); DDRB |= _BV(MOSI); //pinMode(MISO_PIN, INPUT); //pinMode(SCK, OUTPUT); DDRB |= _BV(SCK); #if SPI_INIT_SLOW // Enable SPI, Master, clock rate f_osc/128 SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); #else // SPI_INIT_SLOW // Enable SPI, Master, clock rate f_osc/64 SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1); #endif // SPI_INIT_SLOW // must supply min of 74 clock cycles with CS high. for (i = 0; i < 10; i++) spiSend(0XFF); // next two lines prevent re-init hang by cards that were in partial read spiSSLow(); for (i = 0; i <= 512; i++) spiRec(); // command to go idle in SPI mode for (retry = 0; ; retry++) { if ((r = sdCardCommand(CMD0, 0)) == R1_IDLE_STATE) break; if (retry == 10) { error2(SD_CARD_ERROR_CMD0, r); return 0; } } // check SD version r = sdCardCommand(CMD8, 0x1AA); if (r == R1_IDLE_STATE) { for(i = 0; i < 4; i++) { r = spiRec(); } if (r != 0XAA) { error2(SD_CARD_ERROR_CMD8_ECHO, r); return 0; } sdSetType(SD_CARD_TYPE_SD2); } else if (r & R1_ILLEGAL_COMMAND) { sdSetType(SD_CARD_TYPE_SD1); } else { error2(SD_CARD_ERROR_CMD8, r); } // initialize card and send host supports SDHC if SD2 t0=0; for (;;) { _delay_us(2); t0++; sdCardCommand(CMD55, 0); r = sdCardCommand(ACMD41, sdType() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0); if (r == R1_READY_STATE) break; // timeout after 2 seconds if ((t0/1000) > 2000) { error1(SD_CARD_ERROR_ACMD41); return 0; } } // if SD2 read OCR register to check for SDHC card if (sdType() == SD_CARD_TYPE_SD2) { if(sdCardCommand(CMD58, 0)) { error1(SD_CARD_ERROR_CMD58); return 0; } if ((spiRec() & 0XC0) == 0XC0) sdSetType(SD_CARD_TYPE_SDHC); // discard rest of ocr for (i = 0; i < 3; i++) spiRec(); } // use max SPI frequency unless slow is true SPCR &= ~((1 << SPR1) | (1 << SPR0)); // f_OSC/4 if (!slow) SPSR |= (1 << SPI2X); // Doubled Clock Frequency: f_OSC/2 spiSSHigh(); return 1; }