Skip to content

Commit

Permalink
impros applied
Browse files Browse the repository at this point in the history
  • Loading branch information
TomSaw committed Jul 21, 2024
1 parent 29ac434 commit cc26f13
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 85 deletions.
24 changes: 15 additions & 9 deletions src/modm/driver/motion/adns9800.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ struct adns9800 {
using PeriodType = uint16_t;
using Duration = std::chrono::duration<PeriodType, std::ratio<1, 50_MHz>>;

using DeltaType = int16_t;

// forward declarations
struct Data;
struct Data_Fails;
Expand Down Expand Up @@ -315,12 +317,12 @@ class Adns9800 : public adns9800, public modm::SpiDevice<SpiMaster> {
requires std::is_base_of_v<Data, D>
D
read() {
uint8_t buffer[D::length];
std::array<uint8_t, D::length> buffer;

readTransaction([this, &buffer]() {
SpiMaster::transfer(static_cast<uint8_t>(Register::Motion_Burst));
modm::this_fiber::sleep_for(shutter_config.getOneFrameTime());
SpiMaster::transfer(nullptr, buffer, sizeof(buffer));
SpiMaster::transfer(nullptr, std::begin(buffer), buffer.size());
});

return D(buffer);
Expand All @@ -341,8 +343,10 @@ class Adns9800 : public adns9800, public modm::SpiDevice<SpiMaster> {
template<class Callable>
void
readTransaction(Callable&& closure) {
while(not ready_to_read.isExpired()) modm::this_fiber::yield();
while(not this->acquireMaster()) modm::this_fiber::yield();
while(not ready_to_read.isExpired())
modm::this_fiber::yield();
while(not this->acquireMaster())
modm::this_fiber::yield();
Cs::reset();

std::forward<Callable>(closure)();
Expand All @@ -357,8 +361,10 @@ class Adns9800 : public adns9800, public modm::SpiDevice<SpiMaster> {
template<class Callable>
void
writeTransaction(Callable&& closure) {
while(not ready_to_write.isExpired()) modm::this_fiber::yield();
while(not this->acquireMaster()) modm::this_fiber::yield();
while(not ready_to_write.isExpired())
modm::this_fiber::yield();
while(not this->acquireMaster())
modm::this_fiber::yield();
Cs::reset();

std::forward<Callable>(closure)();
Expand Down Expand Up @@ -386,7 +392,7 @@ class Adns9800 : public adns9800, public modm::SpiDevice<SpiMaster> {

void
writeRegister(const Register reg, const uint8_t data) {
writeTransaction([=]() {
writeTransaction([&]() {
// Setting Bit7 indicates a write
SpiMaster::transfer(static_cast<uint8_t>(reg) | Bit7);
SpiMaster::transfer(data);
Expand All @@ -400,7 +406,7 @@ class Adns9800 : public adns9800, public modm::SpiDevice<SpiMaster> {
modm::this_fiber::sleep_for(shutter_config.getOneFrameTime());
writeRegister(Register::SROM_Enable, 0x18); // Start SROM download

writeTransaction([=]() {
writeTransaction([&]() {
// Setting Bit7 indicates a write
SpiMaster::transfer(static_cast<uint8_t>(Register::SROM_Load_Burst) | Bit7);

Expand All @@ -413,7 +419,7 @@ class Adns9800 : public adns9800, public modm::SpiDevice<SpiMaster> {
});
modm::this_fiber::sleep_for(shutter_config.getOneFrameTime());

// @optimize Request a CRC result of the firmware. @see datasheet P31
// Additionaly, a CRC of the firmware may be requested. @see datasheet P31
}

private:
Expand Down
3 changes: 1 addition & 2 deletions src/modm/driver/motion/adns9800.lb
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ def prepare(module, options):
module.depends(
":processing:resumable",
":architecture:spi.device",
":math:geometry",
":architecture:assert",
":math:geometry"
)
return True

Expand Down
167 changes: 93 additions & 74 deletions src/modm/driver/motion/adns9800_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,91 +25,110 @@
* @author Thomas Sommer
* @ingroup modm_driver_adns9800
*/
namespace modm {
namespace modm
{

/// @brief Relative motion since the last read
struct adns9800::Data {
const modm::Vector<int16_t, 2> delta;
struct adns9800::Data
{
const modm::Vector<DeltaType, 2> delta;

protected:
static constexpr size_t length = 6;
Data(std::span<uint8_t, length> buffer)
: delta{
buffer[3] << 8 | buffer[2], // delta x
buffer[5] << 8 | buffer[4] // delta y
} {}

template <class, class>
friend class Adns9800;
static constexpr size_t length = 6;
Data(std::span<uint8_t, length> buffer)
: delta{
static_cast<DeltaType>(buffer[3] << 8 | buffer[2]),
static_cast<DeltaType>(buffer[5] << 8 | buffer[4])
}
{}

template<class, class>
friend class Adns9800;
};

/// @brief Relative motion and laser fault detection flags
struct adns9800::Data_Fails : public adns9800::Data {
const bool LaserFaultDetected: 1;
const bool LaserPowerValid: 1;
const bool isRunningSROMCode: 1;
struct adns9800::Data_Fails : public adns9800::Data
{
const bool LaserFaultDetected : 1;
const bool LaserPowerValid : 1;
const bool isRunningSROMCode : 1;

protected:
Data_Fails(std::span<uint8_t, length> buffer)
: Data(buffer),
LaserFaultDetected(buffer[0] & Bit6),
LaserPowerValid(buffer[0] & Bit5),
isRunningSROMCode(buffer[1] & Bit6) {
}

template <class, class>
friend class Adns9800;
Data_Fails(std::span<uint8_t, length> buffer)
: Data(buffer),
LaserFaultDetected(buffer[0] & Bit6),
LaserPowerValid(buffer[0] & Bit5),
isRunningSROMCode(buffer[1] & Bit6)
{}

template<class, class>
friend class Adns9800;
};

/// @brief Relative motion, laser fault detection flags and metrics from the shutter unit.
struct adns9800::Data_Fails_Monitoring
: public adns9800::Data_Fails {
struct Statistics {
/**
* Number of features visible by the sensor in the current frame. Range 0 to 169.
* Total number of features: 4 * surface_quality.
* Changes are expected when moving over a surface.
* Convergates to 0 if there is no surface below the sensor.
* surface_quality remains fairly high throughout the Z-height.
*/
const uint8_t surface_quality;
// pixel_sum containes the average pixel value. Range 0 to 223.
// It reports the upper byte of a 17-bit counter which sums all 900 pixels in the current frame
const uint8_t pixel_sum;
// Minium and maximum Pixel value in current frame. Range: 0 to 127.
const uint8_t max_pixel;
const uint8_t min_pixel;
} statistics;

uint8_t getAveragePixelValue() const {
return statistics.pixel_sum << 9 / FrameSize;
}

struct Shutter {
// exposure <= ShutterConfig::exposure_max!
const PeriodType exposure;
// ShutterConfig::period_min <= period <= ShutterConfig::period_max!
const PeriodType period;
} shutter;

Duration getExposureTime() const { return Duration(shutter.exposure); };
Duration getFrameTime() const { return Duration(shutter.period); };
struct adns9800::Data_Fails_Monitoring : public adns9800::Data_Fails
{
struct Statistics
{
/**
* Number of features visible by the sensor in the current frame. Range 0 to 169.
* Total number of features: 4 * surface_quality.
* Changes are expected when moving over a surface.
* Convergates to 0 if there is no surface below the sensor.
* surface_quality remains fairly high throughout the Z-height.
*/
const uint8_t surface_quality;
// pixel_sum containes the average pixel value. Range 0 to 223.
// It reports the upper byte of a 17-bit counter which sums all 900 pixels in the current
// frame
const uint8_t pixel_sum;
// Minium and maximum Pixel value in current frame. Range: 0 to 127.
const uint8_t max_pixel;
const uint8_t min_pixel;
} statistics;

uint8_t
getAveragePixelValue() const
{
return statistics.pixel_sum << 9 / FrameSize;
}

struct Shutter
{
// exposure <= ShutterConfig::exposure_max!
const PeriodType exposure;
// ShutterConfig::period_min <= period <= ShutterConfig::period_max!
const PeriodType period;
} shutter;

Duration
getExposureTime() const
{
return Duration(shutter.exposure);
};
Duration
getFrameTime() const
{
return Duration(shutter.period);
};

protected:
static constexpr size_t length = 14;
Data_Fails_Monitoring(std::span<uint8_t, length> buffer)
: Data_Fails(buffer.subspan<0, Data_Fails::length>()),
statistics{
surface_quality : buffer[6],
pixel_sum : buffer[7],
max_pixel : buffer[8],
min_pixel : buffer[9]
},
shutter{
exposure : buffer[10] << 8 | buffer[11],
period : buffer[12] << 8 | buffer[13],
} {}

template <class, class>
friend class Adns9800;
static constexpr size_t length = 14;
Data_Fails_Monitoring(std::span<uint8_t, length> buffer)
: Data_Fails(buffer.subspan<0, Data_Fails::length>()),
statistics{
surface_quality : buffer[6],
pixel_sum : buffer[7],
max_pixel : buffer[8],
min_pixel : buffer[9]
},
shutter{
exposure : static_cast<PeriodType>(buffer[10] << 8 | buffer[11]),
period : static_cast<PeriodType>(buffer[12] << 8 | buffer[13])
}
{}

template<class, class>
friend class Adns9800;
};
} // namespace modm
} // namespace modm

0 comments on commit cc26f13

Please sign in to comment.