From 4f4501f09d47d0a3ee214b7cd7ec7a1d14b73c45 Mon Sep 17 00:00:00 2001 From: Zakaria Kasmi Date: Mon, 12 Aug 2013 12:29:47 +0200 Subject: [PATCH] small changes + coding conventions + updated files descriptions. --- cpu/lpc2387/i2c/i2c.c | 2 +- drivers/include/lm75a-temp-sensor.h | 254 +++++++++++++++++ drivers/include/srf02-ultrasonic-sensor.h | 91 ++++-- drivers/include/srf08-ultrasonic-sensor.h | 91 +++--- drivers/lm75a/lm75a-temp-sensor.c | 333 ++++++++++++++++++++++ drivers/srf02/srf02-ultrasonic-sensor.c | 119 ++++---- drivers/srf08/srf08-ultrasonic-sensor.c | 266 ++++++++++------- 7 files changed, 927 insertions(+), 229 deletions(-) create mode 100644 drivers/include/lm75a-temp-sensor.h create mode 100644 drivers/lm75a/lm75a-temp-sensor.c diff --git a/cpu/lpc2387/i2c/i2c.c b/cpu/lpc2387/i2c/i2c.c index bd3de787b7..73121a08a7 100644 --- a/cpu/lpc2387/i2c/i2c.c +++ b/cpu/lpc2387/i2c/i2c.c @@ -17,7 +17,7 @@ * user does not declare a handler, an appropriate interrupt is * automatically registered for the specific i2c interface. * - * @author Freie Universität Berlin, Computer Systems & Telematics + * @author Freie Universität Berlin, Computer Systems & Telematics * @author Zakaria Kasmi * @author Marco Ziegert * @author Benjamin Aschenbrenner diff --git a/drivers/include/lm75a-temp-sensor.h b/drivers/include/lm75a-temp-sensor.h new file mode 100644 index 0000000000..e0d9739d8b --- /dev/null +++ b/drivers/include/lm75a-temp-sensor.h @@ -0,0 +1,254 @@ +/* + * lm75a-temp-sensor.h - Definitions of the LM75A temperature sensor driver. + * + * Copyright (C) 2013 Zakaria Kasmi + * + * This source code is licensed under the LGPLv2 license, + * See the file LICENSE for more details. + */ + +/** + * @file + * @internal + * @brief Definitions of the LM75A temperature sensor driver. + * + * The connection between the LM75A and the MCU is based + * on the I2C-interface. + * + * @author Freie Universität Berlin, Computer Systems & Telematics + * @author Zakaria Kasmi + * @version $Revision: 3859 $ + * + * @note $Id: lm75a-temp-sensor.h 3854 2013-09-2 15:35:21 kasmi $ + */ + +#ifndef LM75A_H_ +#define LM75A_H_ + +#include +#include +#include "i2c.h" + +/* LM75A register addresses */ +#define LM75A_ADDR 0x48 +#define LM75A_TEMPERATURE_REG 0x0 +#define LM75A_CONFIG_REG 0x1 +#define LM75A_THYST_REG 0x2 +#define LM75A_OVER_TEMP_REG 0x3 + +/* Define the used I2C Interface */ +//#define LM75A_I2C_INTERFACE I2C0 // P0.27 SDA0, P0.28 SCL0 +#define LM75A_I2C_INTERFACE I2C1_0 // P0.0 SDA1, P0.1 SCL1 +//#define LM75A_I2C_INTERFACE I2C1_1 // P0.19 SDA1, P0.20 SCL1 +//#define LM75A_I2C_INTERFACE I2C2 // P0.10 SDA2, P0.11 SCL2 + +/* LM75A operation modes */ +enum OPERATION_MODES { + LM75A_NORMAL_OPERATION_MODE, + LM75A_SHUTDOWN_MODE, + LM75A_COMPARATOR_MODE, + LM75A_INTERRUPT_MODE +}; + +/*Common definitions for LMA75A */ +#define LM75A_BIT0 0x0 +#define LM75A_BIT1 0x1 +#define LM75A_BIT2 0x2 +#define LM75A_BIT3 0x3 +#define LM75A_BIT4 0x4 +#define LM75A_BIT5 0x5 +#define LM75A_BIT6 0x6 +#define LM75A_BIT7 0x7 +#define LM75A_BIT8 0x8 +#define LM75A_BIT9 0x9 +#define LM75A_BIT10 0xA +#define LM75A_BIT15 0xF +#define LM75A_MOST_SIG_BYTE_MASK 0xFF00 +#define LM75A_LEAST_SIG_BYTE_MASK 0x00FF +#define LM75A_DATA_BITS_MASK 0x07FF +#define LM75A_SIGN_BIT_MASK (1< BIT0, + * Pin1 --> BIT1, Pin2 --> BIT2 = 2^2 = 4 + * @param[in] flags define if the interrupt is generated on rising + * or falling edge (#GPIOINT_RISING_EDGE, + * #GPIOINT_FALLING_EDGE). + * @param[in] handler pointer to an interrupt handler. + * + * @return true if the the external interrupt handler is successfully + * registered, otherwise false. + */ +bool lm75A_ext_irq_handler_register(int32_t port, uint32_t pin_bit_mask, + int32_t flags, void *handler); + + +/** + * @brief Initialize the LM75A temperature sensor. + * The baud rate and the handler for the external interrupt can be + * initialized. The external interrupt handler is optional, if no + * handler is available, the NULL-value can be entered. + * The hysteresis and the over-temperature are displayed before and + * after a rest action is performed. After this the LM7A sensor is + * set in the interrupt or the comparator mode. + * + * @param[in] i2c_interface the i2c interface, several interfaces + * can be selected: i2c0, i2c1 and i2c2. + * @param[in] baud_rate the baud rate. + * @param[in] external_interr_handler pointer to a handler for the external + * interrupt. + * + * @return true if the I2C interface and the external interrupt handler are + * successfully initialized, otherwise false. + */ +bool lm75A_init(uint8_t i2c_interface, uint32_t baud_rate, + void *external_interr_handler); + + +/** + * @brief Register the external interrupt handler for the over-temperature + * shutdown output. + * + * @param[in] handler pointer to a handler for the external interrupts. + * + * @return true if the the external interrupt handler is successfully + * registered, otherwise false. + */ +bool lm75A_external_interrupt_register(void *handler); + + +/** + * @brief Alarm the sensor sampling task about an external interrupt. + * + * @param[in] b is true if an external interrupt is occurred, otherwise false. + * + */ +void lm75A_set_in_alarm(bool b); + +#endif /* LM75A_H_ */ diff --git a/drivers/include/srf02-ultrasonic-sensor.h b/drivers/include/srf02-ultrasonic-sensor.h index 0741fcaa37..eac660e3cd 100644 --- a/drivers/include/srf02-ultrasonic-sensor.h +++ b/drivers/include/srf02-ultrasonic-sensor.h @@ -1,21 +1,25 @@ /* - * sarf02-ultrasonic-sensor.h - Definitions for the SRF02 ultrasonic ranger based on the i2c interface. + * srf02-ultrasonic-sensor.h - Definitions for the SRF02 ultrasonic ranger + * driver. + * * Copyright (C) 2013 Zakaria Kasmi * - * This source code is licensed under the LGPLv2 license, See the file LICENSE for more details. + * This source code is licensed under the LGPLv2 license, + * See the file LICENSE for more details. */ /** * @file * @internal - * @brief Driver definitions for the SRF02 ultrasonic ranger using the LPC2387 chip. - * The connection between the SRF02 and the LPC2387 is based on the i2c interface. + * @brief Driver definitions for the SRF02 ultrasonic ranger. + * The connection between the SRF02 and the MCU is based on + * the i2c interface. * - * @author Freie Universität Berlin, Computer Systems & Telematics - * @author Zakaria Kasmi - * @version $Revision: 3854 $ + * @author Freie Universität Berlin, Computer Systems & Telematics + * @author Zakaria Kasmi + * @version $Revision: 3857 $ * - * @note $Id: sarf02-ultrasonic-sensor.h 3854 2013-06-20 13:30:01Z zkasmi $ + * @note $Id: srf02-ultrasonic-sensor.h 3854 2013-09-03 13:55:30 kasmi $ * */ @@ -23,44 +27,69 @@ #define SRF02_ULTRASONIC_SENSOR_I2C_H_ #include "i2c.h" - /* define the SRF02 registers*/ -#define SRF02_DEFAULT_ADDR 112 -#define SRF02_COMMAND_REG 0x0 -#define SRF02_RANGE_HIGH_BYTE 0x2 -#define SRF02_RANGE_LOW_BYTE 0x3 -#define SRF02_REAL_RANGING_MODE_CM 0x51 - +#define SRF02_DEFAULT_ADDR 112 +#define SRF02_COMMAND_REG 0x0 +#define SRF02_RANGE_HIGH_BYTE 0x2 +#define SRF02_RANGE_LOW_BYTE 0x3 +#define SRF02_REAL_RANGING_MODE_INCH 0x50 +#define SRF02_REAL_RANGING_MODE_CM 0x51 +#define SRF02_REAL_RANGING_MODE_MICRO_SEC 0x52 +#define SRF02_FAKE_RANGING_MODE_INCH 0x56 +#define SRF02_FAKE_RANGING_MODE_CM 0x57 +#define SRF02_FAKE_RANGING_MODE_MICRO_SEC 0x58 /* Define the used I2C Interface */ -//#define SRF02_I2C_INTERFACE I2C0 // P0.27 SDA0, P0.28 SCL0 -//#define SRF02_I2C_INTERFACE I2C1_0 // P0.0 SDA1, P0.1 SCL1 -//#define SRF02_I2C_INTERFACE I2C1_1 // P0.19 SDA1, P0.20 SCL1 -#define SRF02_I2C_INTERFACE I2C2 // P0.10 SDA2, P0.11 SCL2 - -#define SRF02_EXIT_MSG 0 -#define SRF02_RANGING_MSG 1 -#define SRF02_SLEEP_MSG 2 -#define SRF02_WEAKUP_MSG 3 +//#define SRF02_I2C_INTERFACE I2C0 // P0.27 SDA0, P0.28 SCL0 +//#define SRF02_I2C_INTERFACE I2C1_0 // P0.0 SDA1, P0.1 SCL1 +//#define SRF02_I2C_INTERFACE I2C1_1 // P0.19 SDA1, P0.20 SCL1 +#define SRF02_I2C_INTERFACE I2C2 // P0.10 SDA2, P0.11 SCL2 +#define SRF02_EXIT_MSG 0 +#define SRF02_RANGING_MSG 1 +#define SRF02_SLEEP_MSG 2 +#define SRF02_WEAKUP_MSG 3 /** - * @brief Initialize the SRF02 ultrasonic sensor. + * @brief Initialize the SRF02 ultrasonic sensor. * - * @param[in] i2c_interface the i2c interface, several interfaces can be selected: i2c0, i2c1 and i2c2. - * @param[in] baud_rate the baud rate. + * @param[in] i2c_interface the i2c interface, several interfaces can be + * selected: i2c0, i2c1 and i2c2. + * @param[in] baud_rate the baud rate. * - *@return true if the SRF02 is successfully initialized, otherwise false. + * @return true if the SRF02 is successfully initialized, otherwise false. */ bool srf02_init(uint8_t i2c_interface, uint32_t baud_rate); /** - * @brief Start a continuous sampling of the distance measures. - * This function prints the distance values in centimeters over the rs232 interface. + * @brief Get the distance measured from the SRF02 ultrasonic sensor. + * The result of a ranging can be returned in inches, + * centimeters or microseconds + * + * @param[in] ranging_mode there are three real ranging modes, which return + * the result in inches, centimeters or microseconds. + * Another set of three fake ranging modes do the same + * but without transmitting the burst. + * + * @return the ranging result in inches, centimeters or microseconds. In the + * case of the fake ranging mode a zero value is returned. UINT32_MAX + * is returned if write/read action from the i2c-interface is failed. + * + */ +uint32_t srf02_get_distance(uint8_t ranging_mode); + +/** + * @brief Start a continuous sampling of the distance measures. + * This function prints the distance values over the rs232 + * interface. + * + * @param[i] ranging_mode there are three real ranging modes, which return + * the result in inches, centimeters or microseconds. + * Another set of three fake ranging modes do the same + * but without transmitting the burst. * */ void srf02_start_ranging(void); - #endif /* SRF02_ULTRASONIC_SENSOR_I2C_H_ */ diff --git a/drivers/include/srf08-ultrasonic-sensor.h b/drivers/include/srf08-ultrasonic-sensor.h index 60d201557d..3bcb8ae761 100644 --- a/drivers/include/srf08-ultrasonic-sensor.h +++ b/drivers/include/srf08-ultrasonic-sensor.h @@ -1,22 +1,24 @@ /* - * sarf08-ultrasonic-sensor.h - Definitions for the SRF02 ultrasonic ranger using the LPC2387 chip. + * srf08-ultrasonic-sensor.h - Definitions for the SRF08 ultrasonic ranger. + * * Copyright (C) 2013 Zakaria Kasmi * - * This source code is licensed under the LGPLv2 license, + * This source code is licensed under the LGPLv2 license, * See the file LICENSE for more details. */ /** * @file * @internal - * @brief Driver definitions for the SRF08 ultrasonic ranger using the LPC2387 chip. The communication - * between the LPC23 chip and SRF08 is via the i2c interface + * @brief Driver definitions for the SRF08 ultrasonic. + * The communication between the MCU and SRF08 is via the i2c + * interface. * - * @author Freie Universität Berlin, Computer Systems & Telematics - * @author Zakaria Kasmi - * @version $Revision: 3854 $ + * @author Freie Universität Berlin, Computer Systems & Telematics + * @author Zakaria Kasmi + * @version $Revision: 3857 $ * - * @note $Id: sarf08-ultrasonic-sensor.h 3854 2013-06-21 12:30:01Z zkasmi $ + * @note $Id: srf08-ultrasonic-sensor.h 3854 2013-09-03 14:06:23 kasmi $ * */ @@ -24,65 +26,67 @@ #define SRF08_ULTRASONIC_SENSOR_I2C_H_ /* define the SRF02 registers*/ -#define SRF08_DEFAULT_ADDR 112 -#define SRF08_COMMAND_REG 0x0 -#define SRF08_RANGE_HIGH_BYTE 0x2 -#define SRF08_RANGE_LOW_BYTE 0x3 -#define SRF08_REAL_RANGING_MODE_CM 0x51 -#define SRF08_RANGE_REG 0x2 -#define SRF08_GAIN_REG 0x1 +#define SRF08_DEFAULT_ADDR 112 +#define SRF08_COMMAND_REG 0x0 +#define SRF08_RANGE_HIGH_BYTE 0x2 +#define SRF08_RANGE_LOW_BYTE 0x3 +#define SRF08_REAL_RANGING_MODE_CM 0x51 +#define SRF08_RANGE_REG 0x2 +#define SRF08_GAIN_REG 0x1 -#define MAX_REGISTER_NUMBER 35 +#define SRF08_MAX_REGISTER_NUMBER 35 +#define SRF08_MAX_ECHO_NUMBER 17 /* Define the used I2C Interface */ -//#define I2C_INTERFACE I2C0 // P0.27 SDA0, P0.28 SCL0 -//#define I2C_INTERFACE I2C1_0 // P0.0 SDA1, P0.1 SCL1 -//#define I2C_INTERFACE I2C1_1 // P0.19 SDA1, P0.20 SCL1 -#define SRF08_I2C_INTERFACE I2C2 // P0.10 SDA2, P0.11 SCL2 +//#define I2C_INTERFACE I2C0 // P0.27 SDA0, P0.28 SCL0 +//#define I2C_INTERFACE I2C1_0 // P0.0 SDA1, P0.1 SCL1 +//#define I2C_INTERFACE I2C1_1 // P0.19 SDA1, P0.20 SCL1 +#define SRF08_I2C_INTERFACE I2C2 // P0.10 SDA2, P0.11 SCL2 /** - * @brief Initialize the SRF08 ultrasonic sensor. + * @brief Initialize the SRF08 ultrasonic sensor. * - * @param[in] i2c_interface the i2c interface, several interfaces can be selected: i2c0, i2c1 and i2c2. - * @param[in] baud_rate the baud rate. + * @param[in] i2c_interface the i2c interface, several interfaces can be + * selected: i2c0, i2c1 and i2c2. + * @param[in] baud_rate the baud rate. * - *@return true if the SRF08 is successfully initialized, otherwise false. + * @return true if the SRF08 is successfully initialized, otherwise false. * */ - bool srf08_init(uint8_t i2c_interface, uint32_t baud_rate); /** - * @brief Start a continuous distance ranging with the SRF08 ultrasonic range-finder. - * The ranging results are given in centimeters over the RS232-Interface. + * @brief Start a continuous distance ranging with the SRF08 ultrasonic + * range-finder. + * The ranging results are given over the RS232-Interface. * */ void srf08_start_ranging(void); /** - * @brief Set the maximum range of the SRF08. + * @brief Set the maximum range of the SRF08. * - * @param[in] max_range the adjusted maximal range is: max_range = (max_rangex43mm) + 43mm. + * @param[in] max_range the adjusted maximal range is: + * max_range = (max_rangex43mm) + 43mm. * */ void srf08_set_range(uint8_t max_range); - /** - * @brief Set the maximum of the analog stages. + * @brief Set the maximum of the analog stages. * - * @param[in] max_gain the maximal gain value. + * @param[in] max_gain the maximal gain value. * */ void srf08_set_gain(uint8_t max_gain); /** - * @brief Get the maximal range. + * @brief Get the maximal range. * * * @return the maximal range value. @@ -91,11 +95,30 @@ uint8_t srf08_get_range(void); /** - * @brief Get the maximal analog gain. + * @brief Get the maximal analog gain. * * * @return the maximal gain value. */ uint8_t srf08_get_gain(void); + +/** + * @brief Get all distances measured from the SRF08 ultrasonic + * sensor. The results of a ranging can be returned in inches, + * centimeters or microseconds. The SRF08 can detect up to + * targets. This function prints the distance values over + * the rs232 interface + * + * @param[in] range_array a pointer to a buffer holding the ranging results. + * @param[in] ranging_mode there are three real ranging modes, which return + * the result in inches, centimeters or microseconds. + * Another set of three fake ranging modes do the same + * but without transmitting the burst. + * + * @return -1 if the write/read action from the i2c-interface is failed, + * otherwise the number of the detected targets is delivered. + */ +int32_t srf08_get_distances(uint32_t *range_array, uint8_t ranging_mode); + #endif /* SRF08_ULTRASONIC_SENSOR_I2C_H_ */ diff --git a/drivers/lm75a/lm75a-temp-sensor.c b/drivers/lm75a/lm75a-temp-sensor.c new file mode 100644 index 0000000000..b257e28f62 --- /dev/null +++ b/drivers/lm75a/lm75a-temp-sensor.c @@ -0,0 +1,333 @@ +/* + * lm75a-temp-sensor.c - Driver for the LM75A temperature sensor based on the + * i2c interface. + * + * Copyright (C) 2013 Zakaria Kasmi + * + * This source code is licensed under the LGPLv2 license, + * See the file LICENSE for more details. + * + */ + +/** + * @file + * @internal + * @brief Driver for the LM75A temperature sensor. + * The communication between the LM75A and the MCU is + * based on the i2c interface. + * + * @author Freie Universität Berlin, Computer Systems & Telematics + * @author Zakaria Kasmi + * @version $Revision: 3854 $ + * + * @note $Id: lm75a-temp-sensor.c 3854 2013-09-03 13:56:47 kasmi $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lpc2387.h" +#include "gpioint.h" +#include "i2c.h" +#include "lm75a-temp-sensor.h" +#include "hwtimer.h" +#include "board.h" + +//declaration as volatile is important, otherwise no interrupt is triggered. +volatile bool my_alarm = false; + +static uint16_t get_2s_complement(uint16_t num) +{ + return ~(num) + 1; +} + +//Write: MC --> Sensor +static void to_bytes(float_t f, uint8_t *buff) +{ + int32_t i = (int32_t)(f * 2); + buff[0] = (uint8_t)((i >> LM75A_BIT1) & 0xFF);//Most signif. byte + buff[1] = (uint8_t)((i & LM75A_BIT1) << LM75A_BIT7);//Least signif. byte +} + +static uint16_t to_uint16(uint8_t *buff) +{ + if (buff != NULL) { + return (buff[0] << LM75A_BIT8) | buff[1]; + } + else { + return UINT16_MAX; + } +} + +//Read: Sensor --> MC +volatile static float_t to_float(uint8_t reg_addr, uint16_t reg_value) +{ + + uint16_t sign = reg_value & LM75A_SIGN_BIT_MASK; + float_t f_temp = 0.0; + float_t factor = 0.0; + + switch (reg_addr) { + case LM75A_OVER_TEMP_REG: + case LM75A_THYST_REG: + factor = 0.5; + break; + + case LM75A_TEMPERATURE_REG: + factor = 0.125; + } + + if (sign) { //the number is negative + f_temp = (get_2s_complement(reg_value) & LM75A_DATA_BITS_MASK) + * -factor; + } + else { //the number is positive + f_temp = reg_value * factor; + + } + + return f_temp; +} + +static void set_register(uint8_t i2c_interface, uint8_t reg_addr, float_t value) +{ + bool status = false; + uint8_t tx_buff[2]; + + switch (reg_addr) { + case LM75A_OVER_TEMP_REG: + case LM75A_THYST_REG: + to_bytes(value, tx_buff); + status = i2c_write(i2c_interface, LM75A_ADDR, reg_addr, tx_buff, 2); + break; + + case LM75A_CONFIG_REG: + tx_buff[0] = (uint8_t) value; + status = i2c_write(i2c_interface, LM75A_ADDR, reg_addr, tx_buff, 1); + } + + if (!status) { + puts( + "[lm75a_tempSensorI2C/lm75A_setRegister]: Slave is not ready !!\n"); + } +} + +void lm75A_set_over_temperature(float_t tos) +{ + set_register(LM75A_I2C_INTERFACE, LM75A_OVER_TEMP_REG, tos); +} + +void lm75A_set_hysteresis_temperature(float_t thsyt) +{ + set_register(LM75A_I2C_INTERFACE, LM75A_THYST_REG, thsyt); +} + +static uint16_t lm75A_get_register_value(uint8_t i2c_interface, + uint8_t reg_addr, + uint8_t reg_size) +{ + bool status = false; + uint8_t rx_buff[reg_size]; + + i2c_clear_buffer(rx_buff, reg_size); + + if ((reg_size > 0) && (reg_size < 3)) { + + status = i2c_read(i2c_interface, LM75A_ADDR, reg_addr, rx_buff, + reg_size); + + if (!status) { //Slave is not ready + puts( + "[lm75a_tempSensorI2C/lm75A_getConfigReg]: Slave is not\ + ready !\n"); + + if (reg_size < 2) { + return UCHAR_MAX; + } + else { + return UINT16_MAX; + } + } + else { //Slave acknowledged + if (reg_size < 2) { + return rx_buff[0]; + } + else { + return to_uint16(rx_buff); + } + } + } + else { + puts("the register size must be less than 2"); + return UINT16_MAX; + } +} + +uint8_t lm75A_get_config_reg(void) +{ + return lm75A_get_register_value(LM75A_I2C_INTERFACE, LM75A_CONFIG_REG, 1); +} + +float_t lm75A_get_hysteresis_temperature(void) +{ + uint16_t hyst_reg_value = 0; + hyst_reg_value = lm75A_get_register_value(LM75A_I2C_INTERFACE, + LM75A_THYST_REG, 2); + hyst_reg_value = (hyst_reg_value >> LM75A_BIT7); + return to_float(LM75A_THYST_REG, hyst_reg_value); +} + +float_t lm75A_get_over_temperature(void) +{ + uint16_t over_temp = 0; + + over_temp = lm75A_get_register_value(LM75A_I2C_INTERFACE, + LM75A_OVER_TEMP_REG, 2); + over_temp = (over_temp >> LM75A_BIT7); + return to_float(LM75A_OVER_TEMP_REG, over_temp); +} + +float_t lm75A_get_ambient_temperature(void) +{ + uint16_t amb_temp = 0; + amb_temp = lm75A_get_register_value(LM75A_I2C_INTERFACE, + LM75A_TEMPERATURE_REG, 2); + amb_temp = (amb_temp >> LM75A_BIT5); + return to_float(LM75A_TEMPERATURE_REG, amb_temp); +} + +void lm75A_reset(void) +{ + lm75A_set_over_temperature(LM75A_DEFAULT_TOS); + lm75A_set_hysteresis_temperature(LM75A_DEFAULT_THYST); + set_register(LM75A_I2C_INTERFACE, LM75A_CONFIG_REG, + LM75A_DEFAULT_CONFIG_VALUE); + +} + +void lm75A_set_operation_mode(uint8_t op_mode) +{ + uint8_t config_reg = lm75A_get_config_reg(); + + switch (op_mode) { + case LM75A_NORMAL_OPERATION_MODE: + config_reg &= ~(1 << LM75A_BIT0); + break; + + case LM75A_SHUTDOWN_MODE: + config_reg |= (1 << LM75A_BIT0); + break; + + case LM75A_COMPARATOR_MODE: + config_reg &= ~(1 << LM75A_BIT1); + break; + + case LM75A_INTERRUPT_MODE: + config_reg |= (1 << LM75A_BIT1); + break; + + default: + config_reg &= ~(1 << LM75A_BIT0); + } + + set_register(LM75A_I2C_INTERFACE, LM75A_CONFIG_REG, config_reg); +} + +bool lm75A_ext_irq_handler_register(int32_t port, uint32_t pin_bit_mask, + int32_t flags, void *handler) +{ + return gpioint_set(port, pin_bit_mask, flags, handler); +} + +bool lm75A_init(uint8_t i2c_interface, uint32_t baud_rate, + void *external_interr_handler) +{ + if (i2c_initialize(i2c_interface, (uint32_t) I2CMASTER, 0, baud_rate, NULL) + == false) { /* initialize I2C */ + puts("fatal error!happened in i2cInitialize() \n"); + + while (1) + ; /* Fatal error */ + } + + //i2c_enable_pull_up_resistor(i2c_interface); + i2c_disable_pull_up_resistor(i2c_interface); + + if ((external_interr_handler != NULL) + && lm75A_ext_irq_handler_register(2, BIT3, GPIOINT_FALLING_EDGE, + external_interr_handler)) { + printf("# %-70s%10s\n", "External interrupt handler registration", + "...[OK]"); + } + else { + printf("# %-70s%10s\n", "External interrupt handler registration", + "...[FAILED]"); + return false; + } + + puts("################## Before reset ##################"); + printf("configReg = %u\n", lm75A_get_config_reg()); + printf("hystTemp = %f\n", lm75A_get_hysteresis_temperature()); + printf("overTemp = %f\n", lm75A_get_over_temperature()); + lm75A_reset(); + + puts("\n################## After reset ##################"); + printf("configRegInitial = %u\n", lm75A_get_config_reg()); + printf("initialHystTemp = %f\n", lm75A_get_hysteresis_temperature()); + printf("initialOverTemp = %f\n", lm75A_get_over_temperature()); + + puts("\n################## New configuration ##################"); + // set the hysteresis temperature + lm75A_set_hysteresis_temperature(32.0); + printf("hystTemp = %f\n", lm75A_get_hysteresis_temperature()); + lm75A_set_over_temperature(33.0); + printf("overTemp = %f\n", lm75A_get_over_temperature()); + + puts("\n################## Go to comparator mode ##################"); + lm75A_set_operation_mode(LM75A_COMPARATOR_MODE); + printf("configReg = %u\n", lm75A_get_config_reg()); + // puts("\n################## Go to interrupt mode ##################"); + // lm75A_set_operation_mode(LM75A_INTERRUPT_MODE); + // printf("configReg = %u\n", lm75A_get_config_reg()); + + return true; +} + +void lm75A_set_in_alarm(bool b) +{ + my_alarm = b; +} + +/* + * Application entry point. + */ +void lm75A_start_sensor_sampling(void (*handler)(void)) +{ + /* + * Normal main() thread activity. + */ + while (true) { + //Toggle the green LED; + LED_RED_TOGGLE; + printf("amb_temp = %3.3f\n", lm75A_get_ambient_temperature()); + + if (my_alarm && (handler != NULL)) { + LED_GREEN_ON; + handler(); + my_alarm = false; + } + + hwtimer_wait(HWTIMER_TICKS(100000)); + LED_RED_TOGGLE; + hwtimer_wait(HWTIMER_TICKS(100000)); + } +} + + diff --git a/drivers/srf02/srf02-ultrasonic-sensor.c b/drivers/srf02/srf02-ultrasonic-sensor.c index 407ffa8eaa..cc3e470b5a 100644 --- a/drivers/srf02/srf02-ultrasonic-sensor.c +++ b/drivers/srf02/srf02-ultrasonic-sensor.c @@ -1,21 +1,24 @@ /* - * sarf02-ultrasonic-sensor.c - Driver for the SRF02 ultrasonic sensor using the LPC2387 chip. + * srf02-ultrasonic-sensor.c - Driver for the SRF02 ultrasonic. + * * Copyright (C) 2013 Zakaria Kasmi * - * This source code is licensed under the LGPLv2 license, See the file LICENSE for more details. + * This source code is licensed under the LGPLv2 license, + * See the file LICENSE for more details. */ /** * @file * @internal - * @brief Driver for the SRF02 ultrasonic ranger using the LPC2387 chip. - * The connection between the LPC2387 and the SRF08 is based on the i2c-interface. + * @brief Driver for the SRF02 ultrasonic ranger. + * The connection between the MCU and the SRF08 is based on the + * i2c-interface. * - * @author Freie Universität Berlin, Computer Systems & Telematics - * @author Zakaria Kasmi + * @author Freie Universität Berlin, Computer Systems & Telematics + * @author Zakaria Kasmi * @version $Revision: 3854 $ * - * @note $Id: sarf02-ultrasonic-sensor.c 3854 2013-06-05 13:30:01Z zkasmi $ + * @note $Id: srf02-ultrasonic-sensor.c 3857 2013-09-03 15:50:13 kasmi $ * */ @@ -30,59 +33,69 @@ #include "srf02-ultrasonic-sensor.h" #include "i2c.h" +bool srf02_init(uint8_t i2c_interface, uint32_t baud_rate) +{ + if (i2c_initialize(i2c_interface, (uint32_t) I2CMASTER, 0, baud_rate, NULL) + == false) { /* initialize I2C */ + puts("fatal error!happened in i2cInitialize() \n"); -bool srf02_init(uint8_t i2c_interface, uint32_t baud_rate) { - if (i2c_initialize(i2c_interface, (uint32_t) I2CMASTER, 0, baud_rate, NULL) - == false) /* initialize I2C */ - { - puts("fatal error! happened in i2cInitialize() \n"); - while (1) - ; /* Fatal error */ - } else { - i2c_enable_pull_up_resistor(i2c_interface); - //i2c_disable_pull_up_resistor(i2c_interface); - return true; - } - + while (1) + ; /* Fatal error */ + } + else { + i2c_enable_pull_up_resistor(i2c_interface); + //i2c_disable_pull_up_resistor(i2c_interface); + return true; + } } +uint32_t srf02_get_distance(uint8_t ranging_mode) +{ + bool status = false; + uint8_t reg_size = 1; + uint8_t range_high_byte = 0; + uint8_t range_low_byte = 0; + uint32_t distance = 0; + uint8_t rx_buff[reg_size]; + uint8_t tx_buff[reg_size]; + tx_buff[0] = SRF02_REAL_RANGING_MODE_CM; + while (1) { + status = i2c_write(SRF02_I2C_INTERFACE, SRF02_DEFAULT_ADDR, + SRF02_COMMAND_REG, tx_buff, reg_size); -void srf02_start_ranging(void) { - bool status = false; - uint8_t reg_size = 1; - uint8_t range_high_byte = 0; - uint8_t range_low_byte = 0; - uint32_t distance = 0; - uint8_t rx_buff[reg_size]; - uint8_t tx_buff[reg_size]; - tx_buff[0] = SRF02_REAL_RANGING_MODE_CM; + distance = srf02_get_distance(ranging_mode); - while (1) { - status = i2c_write(SRF02_I2C_INTERFACE, SRF02_DEFAULT_ADDR, - SRF02_COMMAND_REG, tx_buff, reg_size); - if(!status){ - puts("Write the ranging command to the i2c-interface is failed"); - break; - } - hwtimer_wait(HWTIMER_TICKS(65000)); - status = i2c_read(SRF02_I2C_INTERFACE, SRF02_DEFAULT_ADDR, - SRF02_RANGE_HIGH_BYTE, rx_buff, reg_size); - if(!status){ - puts("Read the distance from the i2c-interface is failed"); - break; - } - range_high_byte = rx_buff[0]; + if (distance != UINT32_MAX) { + switch (ranging_mode) { + case SRF02_REAL_RANGING_MODE_CM : + printf("distance = %lu cm\n", distance); + break; - status = i2c_read(SRF02_I2C_INTERFACE, SRF02_DEFAULT_ADDR, - SRF02_RANGE_LOW_BYTE, rx_buff, reg_size); - range_low_byte = rx_buff[0]; + case SRF02_REAL_RANGING_MODE_INCH : + printf("distance = %lu inch\n", distance); + break; - distance = (range_high_byte << 8) | range_low_byte; - printf("distance = %lu cm\n", distance); - //printf("%u | %u\n", range_high_byte, range_low_byte); - hwtimer_wait(HWTIMER_TICKS(50000)); - } + case SRF02_REAL_RANGING_MODE_MICRO_SEC: + // dist_m = 0.000172 distance_micro_sec (air) + printf("distance = %lu micro_sec\n", distance); + break; - puts("The SRF02 range sampling is ended!!"); + case SRF02_FAKE_RANGING_MODE_CM: + case SRF02_FAKE_RANGING_MODE_INCH: + case SRF02_FAKE_RANGING_MODE_MICRO_SEC: + printf("distance fake ranging = %lu \n", distance); + break; + + default: + printf("distance = %lu cm\n", distance); + } + + hwtimer_wait(HWTIMER_TICKS(50000)); + } + else { + break; + } + } + puts("The SRF02 range sampling is ended!!"); } diff --git a/drivers/srf08/srf08-ultrasonic-sensor.c b/drivers/srf08/srf08-ultrasonic-sensor.c index d2b57f4641..5ad0d170d4 100644 --- a/drivers/srf08/srf08-ultrasonic-sensor.c +++ b/drivers/srf08/srf08-ultrasonic-sensor.c @@ -1,21 +1,23 @@ /* - * srf08-ultrasonic-sensor.c - Driver for the SRF08 ultrasonic ranger and the LPC2387 chip via the i2c interface. + * srf08-ultrasonic-sensor.c - Driver for the SRF08 ultrasonic ranger via the + * i2c interface. + * * Copyright (C) 2013 Zakaria Kasmi * - * This source code is licensed under the LGPLv2 license, + * This source code is licensed under the LGPLv2 license, * See the file LICENSE for more details. */ /** * @file * @internal - * @brief Driver for the SRF08 ultrasonic ranger and the LPC2387 chip using the i2c interface. + * @brief Driver for the SRF08 ultrasonic ranger using the i2c interface. * - * @author Freie Universität Berlin, Computer Systems & Telematics - * @author Zakaria Kasmi + * @author Freie Universität Berlin, Computer Systems & Telematics + * @author Zakaria Kasmi * @version $Revision: 3854 $ * - * @note $Id: srf08-ultrasonic-sensor.c 3854 2013-06-21 15:30:01Z zkasmi $ + * @note $Id: srf08-ultrasonic-sensor.c 3857 2013-09-02 16:45:49 kasmi $ * */ @@ -26,116 +28,160 @@ #include "srf08-ultrasonic-sensor.h" #include "i2c.h" +bool srf08_init(uint8_t i2c_interface, uint32_t baud_rate) +{ + if (i2c_initialize(i2c_interface, (uint32_t) I2CMASTER, 0, baud_rate, NULL) + == false) { /* initialize I2C */ + puts("fatal error!happened in i2cInitialize() \n"); -bool srf08_init(uint8_t i2c_interface, uint32_t baud_rate) { - if (i2c_initialize(i2c_interface, (uint32_t) I2CMASTER, 0, baud_rate, NULL) - == false) /* initialize I2C */ - { - puts("fatal error! happened in i2cInitialize() \n"); - while (1) - ; /* Fatal error */ - } else { - i2c_enable_pull_up_resistor(i2c_interface); - //i2c_disable_pull_up_resistor(i2c_interface); - return true; - } + while (1) + ; /* Fatal error */ + } + else { + i2c_enable_pull_up_resistor(i2c_interface); + //i2c_disable_pull_up_resistor(i2c_interface); + return true; + } +} +void srf08_set_range(uint8_t max_range) +{ + uint8_t tx_buff[1]; + tx_buff[0] = max_range; + i2c_write(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, SRF08_RANGE_REG, tx_buff, + 1); +} + +void srf08_set_gain(uint8_t gain) +{ + uint8_t tx_buff[1]; + tx_buff[0] = gain; + i2c_write(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, SRF08_GAIN_REG, tx_buff, + 1); +} + +uint8_t srf08_get_range(void) +{ + uint8_t rx_buff[1]; + i2c_read(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, SRF08_RANGE_REG, rx_buff, + 1); + + return rx_buff[0]; +} + +uint8_t srf08_get_gain(void) +{ + uint8_t rx_buff[1]; + i2c_read(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, SRF08_GAIN_REG, rx_buff, + 1); + + return rx_buff[0]; } -void srf08_set_range(uint8_t max_range) { - uint8_t tx_buff[1]; - tx_buff[0] = max_range; - i2c_write(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, SRF08_RANGE_REG, tx_buff, - 1); +int32_t srf08_get_distances(uint32_t *range_array, uint8_t ranging_mode) +{ + bool status = false; + uint8_t reg_size = 1; + uint8_t range_high_byte = 0; + uint8_t range_low_byte = 0; + uint32_t distance = 0; + uint8_t rx_buff[reg_size]; + uint8_t tx_buff[reg_size]; + uint8_t register_location; + uint8_t echo_number = 0; + + tx_buff[0] = ranging_mode; + status = i2c_write(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, + SRF08_COMMAND_REG, tx_buff, reg_size); + + if (!status) { + puts("Write the ranging command to the i2c-interface is failed"); + return -1; + } + + hwtimer_wait(HWTIMER_TICKS(70000)); + + // Read all echo buffers + for (register_location = 2; register_location < SRF08_MAX_REGISTER_NUMBER; + register_location += 2) { + + //read the high echo byte + status = i2c_read(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, + register_location, rx_buff, reg_size); + + if (!status) { + puts("Read the the high echo byte from the i2c-interface is \ + failed"); + return -1; + } + + range_high_byte = rx_buff[0]; + + //read the low echo byte + status = i2c_read(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, + register_location + 1, rx_buff, reg_size); + + if (!status) { + puts("Read the the low echo byte from the i2c-interface \ + is failed"); + return -1; + } + + range_low_byte = rx_buff[0]; + + if ((range_high_byte == 0) && (range_low_byte == 0)) { + break; + } + else { + distance = (range_high_byte << 8) | range_low_byte; + range_array[(register_location - 2) / 2] = distance; + echo_number++; + + printf("distance = %4lu cm , echo%d\n", + distance, register_location / 2); + } + + hwtimer_wait(HWTIMER_TICKS(500000)); + } + + puts("--------------------------------------------"); + return echo_number; } -void srf08_set_gain(uint8_t gain) { - uint8_t tx_buff[1]; - tx_buff[0] = gain; - i2c_write(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, SRF08_GAIN_REG, tx_buff, - 1); -} - -uint8_t srf08_get_range(void) { - uint8_t rx_buff[1]; - i2c_read(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, SRF08_RANGE_REG, rx_buff, - 1); - - return rx_buff[0]; -} - -uint8_t srf08_get_gain(void) { - uint8_t rx_buff[1]; - i2c_read(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, SRF08_GAIN_REG, rx_buff, - 1); - - return rx_buff[0]; -} - -void srf08_start_ranging(void) { - puts("Ultrasonic SRF08 engine is started"); - bool status = false; - uint8_t reg_size = 1; - uint8_t range_high_byte = 0; - uint8_t range_low_byte = 0; - uint32_t distance = 0; - uint8_t rx_buff[reg_size]; - uint8_t tx_buff[reg_size]; - tx_buff[0] = SRF08_REAL_RANGING_MODE_CM; - uint8_t register_location; - - //wait due to calibration - hwtimer_wait(HWTIMER_TICKS(700000)); - printf("Actual range = %d\n", srf08_get_range()); - printf("Actual gain = %d\n", srf08_get_gain()); - - - while (1) { - - status = i2c_write(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, - SRF08_COMMAND_REG, tx_buff, reg_size); - if (!status) { - puts("Write the ranging command to the i2c-interface is failed"); - break; - } - - hwtimer_wait(HWTIMER_TICKS(70000)); - - // Read all echo buffers - for (register_location = 2; register_location < MAX_REGISTER_NUMBER; - register_location += 2) { - - //read the high echo byte - status = i2c_read(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, - register_location, rx_buff, reg_size); - if (!status) { - puts( - "Read the the high echo byte from the i2c-interface is failed"); - break; - } - range_high_byte = rx_buff[0]; - - //read the low echo byte - status = i2c_read(SRF08_I2C_INTERFACE, SRF08_DEFAULT_ADDR, - register_location + 1, rx_buff, reg_size); - if (!status) { - puts( - "Read the the low echo byte from the i2c-interface is failed"); - break; - } - - range_low_byte = rx_buff[0]; - - if ((range_high_byte == 0) && (range_low_byte == 0)) { - break; - } else { - distance = (range_high_byte << 8) | range_low_byte; - printf("distance = %lu cm , echo%d\n", distance, register_location/2); - } - hwtimer_wait(HWTIMER_TICKS(500000)); - } - } - +void srf08_start_ranging(void) +{ + uint32_t range_array[SRF08_MAX_ECHO_NUMBER]; + uint8_t i; + uint8_t echo_number; + puts("Ultrasonic SRF08 engine is started"); + bool status = false; + uint8_t reg_size = 1; + uint8_t range_high_byte = 0; + uint8_t range_low_byte = 0; + uint32_t distance = 0; + uint8_t rx_buff[reg_size]; + uint8_t tx_buff[reg_size]; + tx_buff[0] = SRF08_REAL_RANGING_MODE_CM; + uint8_t register_location; + + //wait due to calibration + hwtimer_wait(HWTIMER_TICKS(700000)); + printf("Actual range = %d\n", srf08_get_range()); + printf("Actual gain = %d\n", srf08_get_gain()); + + while (1) { + puts("--------------------------------------------"); + echo_number = srf08_get_distances(range_array, SRF08_REAL_RANGING_MODE_CM); + + if (echo_number > 0) { + for (i = 0; i < echo_number; i++) { + printf("stored distance = %4lu cm , echo%d\n", range_array[i], i + 1); + } + } + else { + break; + } + } }