/* * Copyright (C) 2013 Zakaria Kasmi * * This file is subject to the terms and conditions of the GNU Lesser General * Public License v2.1. See the file LICENSE in the top level directory for more * details. */ /** * @ingroup drivers_srf08 * @{ * * @file * @brief Driver for the SRF08 ultrasonic ranger. * The connection between the MCU and the SRF08 is based on the * i2c-interface. * * @author Zakaria Kasmi * @author Peter Kietzmann * @author Kevin Weiss * * @} */ #include #include #include "xtimer.h" #include "periph/i2c.h" #include "srf08.h" #include "srf08_params.h" #define ENABLE_DEBUG 0 #include "debug.h" #define SRF08_DEV_I2C (dev->params.i2c) #define SRF08_DEV_ADDR (dev->params.addr) int srf08_init(srf08_t *dev, const srf08_params_t *params) { dev->params = *params; /* set the maximum range */ if (srf08_set_max_range(dev, SRF08_MAX_RANGE_6M) < 0) { return -3; } /* set the maximum gain */ if (srf08_set_max_gain(dev, SRF08_MAX_GAIN) < 0) { return -4; } return 0; } int srf08_set_max_range(const srf08_t *dev, uint8_t max_range) { int status; /* Acquire exclusive access to the bus. */ i2c_acquire(SRF08_DEV_I2C); status = i2c_write_reg(SRF08_DEV_I2C, SRF08_DEV_ADDR, SRF08_RANGE_REG, max_range, 0); /* Release the bus for other threads. */ i2c_release(SRF08_DEV_I2C); return status; } int srf08_set_max_gain(const srf08_t *dev, uint8_t gain) { int status; /* Acquire exclusive access to the bus. */ i2c_acquire(SRF08_DEV_I2C); status = i2c_write_reg(SRF08_DEV_I2C, SRF08_DEV_ADDR, SRF08_GAIN_REG, gain, 0); /* Release the bus for other threads. */ i2c_release(SRF08_DEV_I2C); return status; } int srf08_get_distances(const srf08_t *dev, uint16_t *range_array, int num_echos, srf08_mode_t ranging_mode) { int status; int echo_number = 0; uint8_t range_bytes[sizeof(uint16_t)]; uint8_t register_location; char max_reg_no_read = (num_echos * sizeof(range_bytes)) +1; /* Acquire exclusive access to the bus. */ i2c_acquire(SRF08_DEV_I2C); /* set ranging mode */ status = i2c_write_reg(SRF08_DEV_I2C, SRF08_DEV_ADDR, SRF08_COMMAND_REG, ranging_mode, 0); /* Release the bus for other threads. */ i2c_release(SRF08_DEV_I2C); if (status != 0) { DEBUG("Write the ranging command to the i2c-interface is failed\n"); return -1; } if(max_reg_no_read > SRF08_MAX_REGISTER_NUMBER) { DEBUG("Too many echos requested. Max. is 17\n"); return -2; } xtimer_usleep(70000); /* read all echo buffers */ for (register_location = 2; register_location < max_reg_no_read; register_location += sizeof(range_bytes)) { /* Acquire exclusive access to the bus. */ i2c_acquire(SRF08_DEV_I2C); /* read the echo bytes */ status = i2c_read_regs(SRF08_DEV_I2C, SRF08_DEV_ADDR, register_location, range_bytes, sizeof(range_bytes), 0); /* Release the bus for other threads. */ i2c_release(SRF08_DEV_I2C); if (status != 0) { DEBUG("Read the echo bytes from the i2c-interface is failed\n"); return -3; } else { uint16_t distance = (range_bytes[0] << 8) | range_bytes[1]; range_array[(register_location - 2) / 2] = distance; echo_number++; } } return echo_number; }