Example #1
0
/************************************************************************
 * Initialize Environment use
 *
 * We are still running from ROM, so data use is limited
 */
int env_init (void)
{
	DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_AMIGAONEG3SE
	enable_nvram();
#endif
#if defined(CFG_NVRAM_ACCESS_ROUTINE)
	ulong crc;
	uchar data[ENV_SIZE];
	nvram_read (&crc, CFG_ENV_ADDR, sizeof(ulong));
	nvram_read (data, CFG_ENV_ADDR+sizeof(ulong), ENV_SIZE);

	if (crc32(0, data, ENV_SIZE) == crc) {
		gd->env_addr  = (ulong)CFG_ENV_ADDR + sizeof(long);
#else
	if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
		gd->env_addr  = (ulong)&(env_ptr->data);
#endif
		gd->env_valid = 1;
	} else {
		gd->env_addr  = (ulong)&default_environment[0];
		gd->env_valid = 0;
	}
#ifdef CONFIG_AMIGAONEG3SE
	disable_nvram();
#endif
	return (0);
}
Example #2
0
INT32 platform_load_nvram_data(PINT8 filename, PINT8 buf, INT32 len)
{
	/* int ret; */
	BT_INFO_FUNC("platform_load_nvram_data ++ BDADDR\n");

	return nvram_read(filename, buf, len, 0);
}
Example #3
0
int platform_load_nvram_data( char * filename, char * buf, int len)
{
    //int ret;
    printk("[wifi] platform_load_nvram_data ++\n");

    return nvram_read( filename, buf, len, 0);
}
int platform_load_nvram_data( char * filename, char * buf, int len)
{
    //int ret;
    BT_INFO_FUNC("platform_load_nvram_data ++ BDADDR\n");

    return nvram_read( filename, buf, len, 0);
}
Example #5
0
/**
 * Dump 256 bytes of NVRAM.
 */
static void dump_nvram(WINDOW *win, int row, int col)
{
	int i, x = 0, y = 0;

	/* Print vertical and horizontal index numbers. */
	for (i = 0; i < 16; i++) {
		mvwprintw(win, ((i < 8) ? 4 : 5) + i, 1, "%2.2X ", i * 0x10);
		mvwprintw(win, 2, 4 + (i * 3), "%2.2X ", i);
	}

	/* Print vertical and horizontal line. */
	for (i = 0; i < 18; i++)
		mvwaddch(win, 3 + i, 3, ACS_VLINE);
	for (i = 0; i < 48; i++)
		mvwaddch(win, 3, 3 + i, (i == 0) ? ACS_ULCORNER : ACS_HLINE);

	/* Dump NVRAM contents. */
	for (i = 1; i < 257; i++) {
		mvwprintw(win, row + y, col + x, "%02x ", nvram_read(i - 1));
		x += 3;
		if (i % 16 == 0) {
			y++;	/* Start a newline after 16 bytes. */
			x = 0;
		}
		if (i % 128 == 0) {
			y++;	/* Add an empty line after 128 bytes. */
			x = 0;
		}
	}
}
Example #6
0
void env_relocate_spec (void)
{
#if defined(CFG_NVRAM_ACCESS_ROUTINE)
	nvram_read(env_ptr, CFG_ENV_ADDR, CFG_ENV_SIZE);
#else
	memcpy (env_ptr, (void*)CFG_ENV_ADDR, CFG_ENV_SIZE);
#endif
}
Example #7
0
uchar env_get_char_spec(int index)
{
	uchar c;

	nvram_read(&c, CONFIG_ENV_ADDR + index, 1);

	return c;
}
Example #8
0
/**
 * @brief Calibrate magnetometer
 *
 * This function measures the magnetometer output if 3 different device
 * orientations, calculates average offset values, and stores these offsets
 * in non-volatile memory.  The offsets will later be used during normal
 * measurements, to compensate for fixed magnetic effects.
 *
 * This routine must be called 3 times total, with the "step" parameter
 * indicating what stage of the calibration is being performed.  This
 * multi-step mechanism allows the application to prompt for physical
 * placement of the sensor device before this routine is called.
 *
 * @param sensor     Address of an initialized sensor device descriptor.
 * @param calib_type The address of a vector storing sensor axis data.
 * @param step       The calibration stage number [1,3].
 * @param info       Unimplemented (ignored) parameter.
 * @return bool     true if the call succeeds, else false is returned.
 */
static bool ak8975_calibrate(sensor_t *sensor,
		sensor_calibration_t calib_type, int step, void *info)
{
	sensor_hal_t *const hal = sensor->hal;
	static vector3_t step_data [3];

	/* Validate the supported calibration types and step number. */
	if ((calib_type != MANUAL_CALIBRATE) || ((step < 1) || (step > 3))) {
		return false;
	}

	/* Read sensor data and test for data overflow. */
	vector3_t *const ptr_step_data = &step_data[ step - 1 ];

	if ((!ak8975_get_data(hal, AK8975_SINGLE_MODE, ptr_step_data)) ||
			ak8975_check_overflow(ptr_step_data)) {
		return false;
	}

	switch (step) {
	/* There's nothing to do on the first two passes. */
	case 1:
	case 2:
		break;

	/* Calculate & update the calibrated offsets on the final pass. */
	case 3:
		calibrated_offsets.x = (step_data[0].x + step_data[1].x) / 2;
		calibrated_offsets.y = (step_data[0].y + step_data[1].y) / 2;
		calibrated_offsets.z = (step_data[1].z + step_data[2].z) / 2;

		/* Write the calibration data then read it back and confirm it
		 * was written correctly
		 */
		nvram_write(0, &calibrated_offsets, sizeof(calibrated_offsets));

		vector3_t read_back;
		nvram_read(0, &read_back, sizeof(vector3_t));

		if (memcmp(&calibrated_offsets, &read_back,
				sizeof(vector3_t))) {
			sensor->err = SENSOR_ERR_IO;
			return false;
		}

		break;

	/* Any other step number is invalid */
	default:
		sensor->err = SENSOR_ERR_PARAMS;
		return false;
	}

	return true;
}
Example #9
0
void env_relocate_spec(void)
{
	char buf[CONFIG_ENV_SIZE];

#if defined(CONFIG_SYS_NVRAM_ACCESS_ROUTINE)
	nvram_read(buf, CONFIG_ENV_ADDR, CONFIG_ENV_SIZE);
#else
	memcpy(buf, (void*)CONFIG_ENV_ADDR, CONFIG_ENV_SIZE);
#endif
	env_import(buf, 1);
}
Example #10
0
bool
platformNvramRead16( void * prAdapter,unsigned char ucWordOffset, unsigned short * pu2Data )
{
    if( pu2Data == NULL )
        return false;
        
    if( nvram_read( WIFI_NVRAM_FILE_NAME, (char *)pu2Data, sizeof(unsigned short), ucWordOffset*sizeof(unsigned short)) != sizeof(unsigned short) )
        return false;
    else 
    	  return true;	
}
Example #11
0
bool
customDataRead8( void * prAdapter,unsigned char ucByteOffset, unsigned char * pucData )
{
    if( pucData == NULL )
        return false;
        
    if( nvram_read( WIFI_NVRAM_CUSTOM_NAME, (char *)pucData, sizeof(unsigned char), ucByteOffset*sizeof(unsigned char)) != sizeof(unsigned char) )
        return false;
    else 
    	  return true;	
}
Example #12
0
/**
 * @brief Calibrate proximity sensor detection thresholds
 *
 * This function measures the proximity sensor output in 3 different steps,
 * one for each channel in the device.  This function should be called when
 * a sample object has been placed at the desired distance from the device
 * to define the threshold for near-proximity detection.  The measured
 * proximity sensor value for each channel is stored in non-volatile memory.
 * These thresholds will later be used to set the threshold during the
 * device initialization sequence.
 *
 * This routine must be called 3 times total, with the "step" parameter
 * indicating what stage of the calibration is being performed (i.e. which
 * channel of the proximity sensor).  This multi-step mechanism allows
 * the application to prompt for physical placement of the object to be
 * detected before this routine is called.
 *
 * @param sensor     Address of an initialized sensor device descriptor.
 * @param calib_type The address of a vector storing sensor axis data.
 * @param step       The calibration stage number [1,3].
 * @param info       Unimplemented (ignored) parameter.
 * @return bool     true if the call succeeds, else false is returned.
 */
static bool sfh7770_calibrate(sensor_t *sensor,
		sensor_calibration_t calib_type, int step, void *info)
{
	sensor_hal_t *const hal = sensor->hal;

	static uint8_t prox_data[3];
	uint8_t read_data[3];

	/* Validate the specified calibration type */
	if (calib_type != MANUAL_CALIBRATE) {
		sensor->err = SENSOR_ERR_PARAMS;
		return false;
	}

	/* Read proximity sensor for individual channel based on step number. */
	switch (step) {
	case 1:
		prox_data[0] = sensor_bus_get(hal, SFH7770_PS_DATA_LED1);
		break;

	case 2:
		prox_data[1] = sensor_bus_get(hal, SFH7770_PS_DATA_LED2);
		break;

	case 3:
		prox_data[2] = sensor_bus_get(hal, SFH7770_PS_DATA_LED3);

		/* Write data */
		nvram_write((SFH7770_NVRAM_OFFSET), prox_data,
				sizeof(prox_data));

		/* Read back data and confirm it was written correctly */
		nvram_read(SFH7770_NVRAM_OFFSET, read_data, sizeof(read_data));

		if (memcmp(prox_data, read_data, sizeof(prox_data))) {
			sensor->err = SENSOR_ERR_IO;
			return false;
		}

		/* Apply stored proximity thresholds from nvram */
		sensor_bus_write(hal, (SFH7770_PS_THR_LED1), read_data,
				sizeof(read_data));

		break;

	/* Any other step number is invalid */
	default:
		sensor->err = SENSOR_ERR_PARAMS;
		return false;
	}

	return true;
}
Example #13
0
uchar env_get_char_spec(int index)
{
#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE
	uchar c;

	nvram_read(&c, CONFIG_ENV_ADDR+index, 1);

	return c;
#else
	return *((uchar *)(gd->env_addr + index));
#endif
}
Example #14
0
static void
i386_detect_memory(void)
{
	size_t npages_extmem;

	// Use CMOS calls to measure available base & extended memory.
	// (CMOS calls return results in kilobytes.)
	npages_basemem = (nvram_read(NVRAM_BASELO) * 1024) / PGSIZE;
	npages_extmem = (nvram_read(NVRAM_EXTLO) * 1024) / PGSIZE;
	// Calculate the number of physical pages available in both base
	// and extended memory.
	if (npages_extmem)
		npages = (EXTPHYSMEM / PGSIZE) + npages_extmem;
	else
		npages = npages_basemem;

	cprintf("Physical memory: %uK available, base = %uK, extended = %uK\n",
		npages * PGSIZE / 1024,
		npages_basemem * PGSIZE / 1024,
		npages_extmem * PGSIZE / 1024);
}
Example #15
0
void env_relocate_spec(void)
{
	char *buf;

#if defined(CONFIG_SYS_NVRAM_ACCESS_ROUTINE)
	buf = env_buf;
	nvram_read(buf, CONFIG_ENV_ADDR, CONFIG_ENV_SIZE);
#else
	buf = (void *)CONFIG_ENV_ADDR;
#endif
	env_import(buf, 1);
}
Example #16
0
/*
 * Initialize Environment use
 *
 * We are still running from ROM, so data use is limited
 */
int env_init(void)
{
#if defined(CONFIG_SYS_NVRAM_ACCESS_ROUTINE)
	ulong crc;
	uchar data[ENV_SIZE];

	nvram_read(&crc, CONFIG_ENV_ADDR, sizeof(ulong));
	nvram_read(data, CONFIG_ENV_ADDR+sizeof(ulong), ENV_SIZE);

	if (crc32(0, data, ENV_SIZE) == crc) {
		gd->env_addr  = (ulong)CONFIG_ENV_ADDR + sizeof(long);
#else
	if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
		gd->env_addr  = (ulong)&(env_ptr->data);
#endif
		gd->env_valid = 1;
	} else {
		gd->env_addr  = (ulong)&default_environment[0];
		gd->env_valid = 0;
	}
	return (0);
}
Example #17
0
static void
i386_detect_memory(void)
{
	unsigned baseval, extval, extabove16mval;

	// Use CMOS calls to measure available base & total memory.
	// This code is BIOS-specific; it works on QEMU, but not necessarily
	// on all hardware. For something more robust, see, e.g., Linux's
	// arch/x86/boot/memory.c.
	// NVRAM_BASE and EXT return results in KB. EXTABOVE16M returns
	// (total memory - 16MB) / 64KB.
	baseval = nvram_read(NVRAM_BASELO);
	extval = nvram_read(NVRAM_EXTLO);
	extabove16mval = nvram_read(NVRAM_EXTABOVE16M_LO);

	// Double-checks.
	if (baseval != 640)
		panic("Physical memory detection error: base != 640K");
	if (extabove16mval != 0 && extval != 65535) {
		cprintf("Physical memory detection warning: BIOS mismatch\n");
		extabove16mval = 0;
	}

	// Set npages based on read values.
	npages_basemem = baseval * 1024 / PGSIZE;
	if (extabove16mval != 0)
		npages = (extabove16mval + (16<<20)/65536) * (65536 / PGSIZE);
	else if (extval != 0)
		npages = (extval * 1024 + EXTPHYSMEM) / PGSIZE;
	else
		npages = npages_basemem;

	cprintf("Physical memory: %uK available\n", npages * PGSIZE / 1024);
	// We can't use more than 256MB.
	if (npages > -KERNBASE / PGSIZE) {
		npages = -KERNBASE / PGSIZE;
		cprintf("(restricting to %uK)\n", npages * PGSIZE / 1024);
	}
}
Example #18
0
uchar env_get_char_spec (int index)
{
#ifdef CFG_NVRAM_ACCESS_ROUTINE
	uchar c;

	nvram_read(&c, CFG_ENV_ADDR+index, 1);

	return c;
#else
	DECLARE_GLOBAL_DATA_PTR;

	return *((uchar *)(gd->env_addr + index));
#endif
}
Example #19
0
int main(void)
{
        uint32_t pos, len;
        board_init();
        nvram_init();

        LED_On(LED0);
        printk("Writing firmware data to flash\n");
        pos = 0;
        while (pos < fw_len) {
                if (fw_len - pos > SECTOR_SIZE)
                        len = SECTOR_SIZE;
                else
                        len = fw_len - pos;

                nvram_write(pos, fw_buf + pos, len);
                pos += len;
        }

        LED_Off(LED0);

        printk("Verifying firmware data\n");
        pos = 0;
        while (pos < fw_len) {
                static uint8_t page_buf[SECTOR_SIZE];
                uint32_t i;

                if (fw_len - pos > SECTOR_SIZE)
                        len = SECTOR_SIZE;
                else
                        len = fw_len - pos;

                nvram_read(pos, page_buf, len);

                for (i = 0; i < len; i++)
                    if (*(page_buf + i) != *(fw_buf + pos + i)) {
                        printk("Verify failed at byte %d, 0x%02x != 0x%02x\n",
                               pos + i, *(page_buf + i), *(fw_buf + pos + i));
                        return 0;
                    }


                pos += len;
        }

        LED_On(LED0);
        printk("Firmware successfully stored in flash!\n");
        return 0;
}
Example #20
0
/* offs buf length -- status actlen */
static int 
rc_nvram_fetch( ulong args[], ulong ret[] ) 
{
	/* printm("RTAS nvram-fetch %04lx %08lX %ld\n", args[0], args[1], args[2] );  */

	ret[1] = nvram_read( args[0], (char*)args[1], args[2] );
	ret[0] = 0;
	if( ret[1] != args[2] ){
		printm("---> nvram_read parameter error\n");
		ret[0] = -3;	/* parameter error */
	}
	/* printm("RTAS nvram-fetch %08lX [len=%d] %02X\n", args[0], args[2], 
		 *(char*)args[1] ); */
	return 0;
}
Example #21
0
void fw_download_cb(void* ctx, uint8_t** buf, uint32_t* len)
{
	/* remember accross different calls */
        static uint8_t* fw_buf = NULL;
        static uint32_t offset = 0;

        /* when firmware download is completed, this function will be invoked
         * on additional time with the input value of len set to 0. we can free
         * the firmware buffer at this time since it's no longer needed.
         */
        if (*len == 0) {
                if (fw_buf)
                        free(fw_buf);
                return;
        }

        /* first call? then initialize flash and allocate a buffer to hold
         * firmware data.
         */
        if (fw_buf == NULL) {
                fw_buf = malloc(BUF_SIZE);

                if (fw_buf == NULL) {
                        printk("could not allocate firmware buffer\n");
                        *len = 0;
                        return;
                }
        }

        /* decide how much to read. we know *len bytes remains, but we only have
         * room for SECTOR_SIEZ bytes in our buffer (fw_buf)
         */
	uint32_t fw_len = *len > BUF_SIZE ? BUF_SIZE : *len;

        /* read data and update output parameters */
        nvram_read(offset, fw_buf, fw_len);
	*buf = fw_buf;
	*len = fw_len;

        /* we need to know where to start reading upon next call */
        offset += fw_len;
}
Example #22
0
/*----------------------------------------------------------------------------*/
BOOLEAN
kalCfgDataRead16(
    IN P_GLUE_INFO_T    prGlueInfo,
    IN UINT_32          u4Offset,
    OUT PUINT_16        pu2Data
    )
{
    if(pu2Data == NULL) {
        return FALSE;
    }

    if(nvram_read(WIFI_NVRAM_FILE_NAME,
                (char *)pu2Data,
                sizeof(unsigned short),
                u4Offset) != sizeof(unsigned short)) {
        return FALSE;
    }
    else {
        return TRUE;
    }
}
Example #23
0
/**
 * Get the current time and date from the RTC
 *
 * @param time A pointer to a broken-down time structure
 */
void rtc_read_clock(struct tm *time)
{
	memset(time, 0, sizeof(*time));

	while(nvram_updating());

	time->tm_mon = bcd2dec(nvram_read(NVRAM_RTC_MONTH)) - 1;
	time->tm_sec = bcd2dec(nvram_read(NVRAM_RTC_SECONDS));
	time->tm_min = bcd2dec(nvram_read(NVRAM_RTC_MINUTES));
	time->tm_mday = bcd2dec(nvram_read(NVRAM_RTC_DAY));
	time->tm_hour = bcd2dec(nvram_read(NVRAM_RTC_HOURS));

	/* Instead of finding the century register,
	   we just make an assumption that if the year value is
	   less then 80, then it is 2000+
	*/

	time->tm_year = bcd2dec(nvram_read(NVRAM_RTC_YEAR));

	if (time->tm_year < 80)
		time->tm_year += 100;
}
/**
 * @brief Honeywell HMC5883L magnetometer driver initialization.
 *
 * This is the main initialization function for the HMC5883L device.
 *
 * @param sensor    Address of a sensor device descriptor.
 * @param resvd     Reserved value.
 * @return bool     true if the call succeeds, else false is returned.
 */
bool hmc5883l_init(sensor_t *sensor, int resvd)
{
	bool status = false;

	sensor_hal_t *const hal = sensor->hal;

	sensor_data_t data;

	if (hmc5883l_device_id(hal,
			&data) && (HMC5883L_DEV_ID == data.device.id)) {
		/* Set the driver function table and capabilities pointer. */
		static const sensor_device_t hmc5883l_device = {
			.func.read      = hmc5883l_read,
			.func.ioctl     = hmc5883l_ioctl,
			.func.selftest  = hmc5883l_selftest,
			.func.calibrate = hmc5883l_calibrate,

			.caps.feature   = SENSOR_CAPS_3_AXIS |
					SENSOR_CAPS_SELFTEST,

			.caps.vendor    = SENSOR_VENDOR_HONEYWELL,
			.caps.units     = SENSOR_UNITS_tesla,
			.caps.scale     = SENSOR_SCALE_micro,
			.caps.name
				= "HMC5883L triaxial compass/magnetometer"
		};

		sensor->drv = &hmc5883l_device;

		/* Enable sensor in continuous measurement mode */
		sensor_bus_put(hal, HMC5883L_MODE_REG, MODE_CONTIN);

		/* Set the driver (device) default range, bandwidth, and
		 * resolution.
		 */
		sensor_bus_put(hal, HMC5883L_CONFIG_REG_A,
				(DATA_RATE_15HZ | MEAS_MODE_NORM));

		hal->range      = range_table[index_130uT].range_units;
		hal->bandwidth  = band_table[index_15hz].bandwidth_Hz;
		hal->resolution = HMC5883L_DATA_RESOLUTION;

		hmc5883l_set_range(hal, index_130uT);
		hmc5883l_set_bandwidth(hal, index_15hz);

		/* Initialize calibration data (offsets & sensitivity) from
		 * NVRAM.
		 */
		nvram_read(0, &cal_data, sizeof(cal_data));

		/* Clear all calibration values if any are invalid. */
		#if defined(MATH_FIXED_POINT)
		if ((cal_data.x == -1) || (cal_data.y == -1) || (cal_data.z == -1)) {
		#else
		if (isnan(cal_data.offsets.x) || isnan(cal_data.offsets.y) ||
				isnan(cal_data.offsets.z)) {
		#endif
			memset(&cal_data, 0x00, sizeof(cal_data));
		}
		
		status = (STATUS_OK == hal->bus.status);
	}

	return status;
}

/**
 * @brief Read magnetometer device ID
 *
 * This function reads the magnetometer hardware identification registers
 * and returns these values to the addresses specified in the function
 * parameters.
 *
 * @param hal       Address of an initialized sensor hardware descriptor.
 * @param data      Address of sensor_data_t structure to return values.
 * @return bool     true if the call succeeds, else false is returned.
 */
static bool hmc5883l_device_id(sensor_hal_t *hal, sensor_data_t *data)
{
	uint32_t id_reg = 0;
	size_t const id_len = 3;

	size_t const count = sensor_bus_read
				(hal, HMC5883L_ID_REG_A, &id_reg, id_len);

	data->device.id  = cpu_to_be32(id_reg) >> 8;
	data->device.version = 0;

	return (count == id_len);
}

/**
 * @brief Read magnetometer vector data.
 *
 * This function obtains magnetometer data for all three axes of the Honeywell
 * device.  The data is read from six device registers using a multi-byte
 * bus transfer.  The 13-bit raw results are then assembled from the two
 * register values for each axis, including extending the sign bit, to
 * form a signed 16-bit value.
 *
 * @param hal       Address of an initialized sensor hardware descriptor.
 * @param data      The address of a vector storing sensor axis data.
 * @return bool     true if the call succeeds, else false is returned.
 */
static bool hmc5883l_get_data(sensor_hal_t *hal, vector3_t *data)
{
	int16_t axis_data[3];    /* input data values:  X,Y,Z */

	/* Ensure that single-measurement mode is set and that bit MR7 is
	 * cleared. Bit MR7 is set internally after each single-measurement
	 * operation.
	 */
	sensor_bus_put(hal, HMC5883L_MODE_REG, MODE_SINGLE);

	do {
		/* Wait for the data ready signal.
		 *
		 * Instead of polling DRDY, as is done below, the device can be
		 * placed in continuous measurement mode and this signal can be
		 * configured to trigger an asynchronous interrupt.
		 */
	} while (gpio_pin_is_low(hal->mcu_sigint /* DRDY input */));

	/* Get measurement data (consecutive big endian byte pairs: x, y, z). */
	hmc588l_axis_t input[3];

	size_t const count = sensor_bus_read
				(hal, HMC5883L_MAG_X_HI, (uint8_t *)input,
				sizeof(input));

	if (count != sizeof(input)) {
		return false;
	}

	/* Note: Device data register order = x, z, y !! */
	axis_data[0] = ((int16_t)((input[0].msb << 8) + input[0].lsb));
	axis_data[2] = ((int16_t)((input[1].msb << 8) + input[1].lsb));
	axis_data[1] = ((int16_t)((input[2].msb << 8) + input[2].lsb));

	if ((axis_data[0] == DATA_OUTPUT_OVERFLOW) ||
			(axis_data[1] == DATA_OUTPUT_OVERFLOW) ||
			(axis_data[2] == DATA_OUTPUT_OVERFLOW)) {
		return false;
	}

	/*
	 * Convert signed integer values to a real data type for calculations.
	 * Use device orientation configuration to assign axes.
	 */
	const sensor_orient_t *const orient = &(hal->orientation);

	data->x = orient->x.sign * axis_data[orient->x.axis];
	data->y = orient->y.sign * axis_data[orient->y.axis];
	data->z = orient->z.sign * axis_data[orient->z.axis];

	return true;
}
/**
 * @brief Calibrate magnetometer
 *
 * This function measures the magnetometer output if 3 different device
 * orientations, calculates average offset values, and stores these offsets
 * in non-volatile memory.  The offsets will later be used during normal
 * measurements, to compensate for fixed magnetic effects.
 *
 * This routine must be called 3 times total, with the "step" parameter
 * indicating what stage of the calibration is being performed.  This
 * multi-step mechanism allows the application to prompt for physical
 * placement of the sensor device before this routine is called.
 *
 * @param sensor    Address of an initialized sensor descriptor.
 * @param data      The address of a vector storing sensor axis data.
 * @param step      The calibration stage number (1 to 3).
 * @param info      Unimplemented (ignored) parameter.
 * @return bool     true if the call succeeds, else false is returned.
 */
bool hmc5883l_calibrate(sensor_t *sensor, sensor_calibration_t calib_type,
		int step, void *info)
{
	static vector3_t step_data[3]; /* sensor readings during calibration */
	vector3_t dummy_data;          /* data from first sensor read (ignored) */
	vector3_t read_back;           /* data read back from nvram to validate */
	sensor_data_t test_data;       /* readings during self test */
	int test_code;                 /* self-test code & result */
	sensor_hal_t *const hal = sensor->hal;

	/* Validate the supported calibration types and step number. */
	if ((calib_type != MANUAL_CALIBRATE) || ((step < 1) || (step > 3))) {
		return false;
	}

	/* During first pass, use self-test to determine sensitivity scaling */
	if (step == 1) {
		/* Run internal self test with known bias field */
		test_code = SENSOR_TEST_BIAS_POS;

		if ((hmc5883l_selftest(sensor, &test_code,
				&test_data) == false) ||
				(test_code != SENSOR_TEST_ERR_NONE)) {
			return false;
		}

		/* Calculate & store sensitivity adjustment values */
		cal_data.sensitivity.x
			= ((scalar_t)HMC5883L_TEST_X_NORM / test_data.axis.x);
		cal_data.sensitivity.z
			= ((scalar_t)HMC5883L_TEST_Z_NORM / test_data.axis.z);
		cal_data.sensitivity.y
			= ((scalar_t)HMC5883L_TEST_Y_NORM / test_data.axis.y);

		nvram_write(CAL_SENSITIVITY_ADDR, &cal_data.sensitivity,
				sizeof(cal_data.sensitivity));

		/* Read back data and confirm it was written correctly */
		nvram_read(CAL_SENSITIVITY_ADDR, &read_back, sizeof(vector3_t));

		if (memcmp(&cal_data.sensitivity, &read_back,
				sizeof(vector3_t))) {
			sensor->err = SENSOR_ERR_IO;
			return false;
		}
	}

	/* Read sensor data and test for data overflow.
	 *   Note: Sensor must be read twice - the first reading may
	 *         contain stale data from previous orientation.
	 */
	if (hmc5883l_get_data(hal, &dummy_data) != true) {
		return false;
	}

	delay_ms(READ_DELAY_MSEC);

	if (hmc5883l_get_data(hal, &(step_data [step - 1])) != true) {
		return false;
	}

	/* Apply sensitivity scaling factors */
	hmc5883l_apply_sensitivity(&(step_data [step - 1]));

	switch (step) {
	/* There's nothing more to do on the first two passes. */
	case 1:
	case 2:
		break;

	/* Calculate & store the offsets on the final pass. */
	case 3:
		cal_data.offsets.x = (step_data[0].x + step_data[1].x) / 2;
		cal_data.offsets.y = (step_data[0].y + step_data[1].y) / 2;
		cal_data.offsets.z = (step_data[1].z + step_data[2].z) / 2;

		nvram_write(CAL_OFFSETS_ADDR, &cal_data.offsets,
				sizeof(cal_data.offsets));

		/* Read back data and confirm it was written correctly */
		nvram_read(0, &read_back, sizeof(vector3_t));

		if (memcmp(&cal_data.offsets, &read_back, sizeof(vector3_t))) {
			sensor->err = SENSOR_ERR_IO;
			return false;
		}

		break;

	default:
		return false;   /* bad step value */
	}

	return true;
}
Example #26
0
unsigned
nvram_read16(unsigned r)
{
	return nvram_read(r) | (nvram_read(r + 1) << 8);
}
Example #27
0
/**
 * @brief Osram SFH7770 light & proximity sensor driver initialization.
 *
 * This is the main initialization function for the SFH7770 device.
 *
 * @param sensor    Address of a sensor device descriptor.
 * @param resvd     Reserved value.
 * @return bool     true if the call succeeds, else false is returned.
 */
bool sfh7770_init(sensor_t *sensor, int resvd)
{
	bool status = false;
	sensor_hal_t *const hal = sensor->hal;

	/* Proximity threshold values from NVRAM */
	struct {
		uint8_t ps_thr_led1;
		uint8_t ps_thr_led2;
		uint8_t ps_thr_led3;
	} prox_thresholds;

	/* Read and check part ID register */
	uint8_t part_id = sensor_bus_get(hal, SFH7770_PART_ID);

	if (part_id == (SFH7770_PART_ID_VAL | SFH7770_PART_REV_VAL)) {
		/* Set the driver function table and capabilities pointer. */
		static const sensor_device_t sfh7770_device = {
			.func.read           = sfh7770_read,
			.func.ioctl          = sfh7770_ioctl,
			.func.calibrate      = sfh7770_calibrate,
			.func.event          = sfh7770_event,
#if 0
			.caps.feature        = XXX
#endif
			.caps.vendor         = SENSOR_VENDOR_OSRAM,
			.caps.units          = SENSOR_UNITS_lux,
			.caps.scale          = SENSOR_SCALE_one,
			.caps.name = "SFH7770 Ambient Light & Proximity Sensor"
		};

		sensor->drv = &sfh7770_device;

		hal->resolution = SFH7770_DATA_RESOLUTION;

		/* Set the device burst read starting register address. */
		hal->burst_addr = SFH7770_ALS_DATA_LSB;

		/* Reset device during first init call */
		if (!sfh7770_initialized) {
			sensor_bus_put(hal, SFH7770_ALS_CONTROL,
					ALS_CONTROL_SW_RESET);
		}

		/* Init light sensor functions if specified */

		if (sensor->type & SENSOR_TYPE_LIGHT) {
			/* Set light sensor mode & interval */

			sensor_bus_put(hal, SFH7770_ALS_CONTROL,
					ALS_MODE_FREE_RUNNING);
			sensor_bus_put(hal, SFH7770_ALS_INTERVAL,
					ALS_INTERVAL_500MS);
		}

		/* Init proximity sensor functions if specified */
		if (sensor->type & SENSOR_TYPE_PROXIMITY) {
			/* Set proximity sensor mode & interval */
			sensor_bus_put(hal, SFH7770_PS_CONTROL,
					PS_MODE_FREE_RUNNING);
			sensor_bus_put(hal, SFH7770_PS_INTERVAL,
					PS_INTERVAL_100MS);

			/* Specify which LEDs are active */
			uint8_t const active_leds = LED_ACTIVE_ALL;
			/* XXX one of: */
			/* XXX  LED_ACTIVE_1    - LED1 only (default) */
			/* XXX  LED_ACTIVE_1_2  - LED1 & LED2 */
			/* XXX  LED_ACTIVE_1_3  - LED1 & LED3 */
			/* XXX  LED_ACTIVE_ALL  - all LEDs */

			/* Set LED current levels */
			uint8_t const led1_curr = I_LED_50MA; /* LED1 current */
			uint8_t const led2_curr = I_LED_50MA; /* LED2 current */
			uint8_t const led3_curr = I_LED_50MA; /* LED3 current */

			sensor_bus_put(hal, SFH7770_I_LED_1_2,
					(active_leds |
					(led2_curr <<
					I_LED2_SHIFT) | led1_curr));

			sensor_bus_put(hal, SFH7770_I_LED_3, led3_curr);

			/* Apply stored proximity thresholds from nvram */
			nvram_read(SFH7770_NVRAM_OFFSET, &prox_thresholds,
					sizeof(prox_thresholds));

			sensor_bus_write(hal, (SFH7770_PS_THR_LED1),
					&prox_thresholds,
					sizeof(prox_thresholds));
		}

		if (!sfh7770_initialized) {
			/* Set interrupt output polarity & mode(active-low,
			 * latched).
			 */
			sensor_bus_put(hal, SFH7770_INT_SET, 0);

			/* Set up interrupt handler */
			if (STATUS_OK == hal->bus.status) {
				sensor_irq_connect(hal->mcu_sigint, sfh7770_isr, hal);
			}
		}

		sfh7770_initialized = true;
		status = true;
	}

	return status;
}

/**
 * @brief Osram SFH7770 driver interrupt service routine.
 *
 * This is the common interrupt service routine for all enabled SFH7770
 * interrupt events.  Three different types of interrupts can be programmed:
 * high light level, low light level, and near proximity.  All share the
 * same interrupt pin and therefore the same ISR entry.
 *
 * @param arg       The address of the driver sensor_hal_t descriptor.
 * @return Nothing.
 */
static void sfh7770_isr(volatile void *arg)
{
	sensor_hal_t *const hal = (sensor_hal_t *)arg;

	struct {                    /* Interrupt register data */
		uint8_t als_data_lsb;   /* light meas data - least signif byte */
		uint8_t als_data_msb;   /* light meas data - most signif byte */
		uint8_t als_ps_status;  /* light & prox sensor status */
		uint8_t ps_data_led1;   /* proximity meas data - LED 1 */
		uint8_t ps_data_led2;   /* proximity meas data - LED 2 */
		uint8_t ps_data_led3;   /* proximity meas data - LED 3 */
		uint8_t int_set;        /* interrupt status */
	}
	regs;

	/* Do not wait for a busy bus when reading data. */
	hal->bus.no_wait = true;
	sensor_bus_read(hal, hal->burst_addr, (uint8_t *)&regs, sizeof(regs));
	hal->bus.no_wait = false;

	if (STATUS_OK == hal->bus.status) {
		static sensor_event_data_t event_data = {.data.scaled = true};

		event_data.data.timestamp = sensor_timestamp();
		event_data.event = SENSOR_EVENT_UNKNOWN;

		/*
		 * Determine the interrupt source then combine measurement
		 * register values into a single 16-bit measurement value.
		 */
		uint8_t const int_source = (regs.int_set & INT_SOURCE_MASK);

		uint16_t const light_level
			= ((regs.als_data_msb << 8) | regs.als_data_lsb);

		switch (int_source) {
		case INT_SOURCE_ALS:

			/* Determine if low or high light interrupt */
			if (light_level >= high_light_threshold) {
				event_data.event = SENSOR_EVENT_HIGH_LIGHT;
				event_data.data.light.value = light_level;

				(event_cb[2].handler)(&event_data,
						event_cb[2].arg);
			} else if (light_level <= low_light_threshold) {
				event_data.event = SENSOR_EVENT_LOW_LIGHT;
				event_data.data.light.value = light_level;

				(event_cb[1].handler)(&event_data,
						event_cb[1].arg);
			}

			return;

		case INT_SOURCE_LED1:
		case INT_SOURCE_LED2:
		case INT_SOURCE_LED3:

			event_data.event = SENSOR_EVENT_NEAR_PROXIMITY;

			if (int_source == INT_SOURCE_LED1) {
				event_data.channel = 1;
			} else if (int_source == INT_SOURCE_LED2) {
				event_data.channel = 2;
			} else { /* INT_SOURCE_LED3 */
				event_data.channel = 3;
			}

			/* Use internal device threshold status to
			 * determine scaled values.
			 */
			event_data.data.proximity.value[0]
				= (regs.als_ps_status & PS_LED1_THRESH) ?
					PROXIMITY_NEAR : PROXIMITY_NONE;

			event_data.data.proximity.value[1]
				= (regs.als_ps_status & PS_LED2_THRESH) ?
					PROXIMITY_NEAR : PROXIMITY_NONE;

			event_data.data.proximity.value[2]
				= (regs.als_ps_status & PS_LED3_THRESH) ?
					PROXIMITY_NEAR : PROXIMITY_NONE;

			(event_cb[0].handler)(&event_data, event_cb[0].arg);
		}
	}
}

/**
 * @brief Read SFH7770 device ID and revision numbers.
 *
 * This function reads the sensor hardware identification registers
 * and returns these values in the specified data structure.
 *
 * @param hal       Address of an initialized sensor hardware descriptor.
 * @param data      Address of sensor_data_t structure to return values.
 * @return bool     true if the call succeeds, else false is returned.
 */
static bool sfh7770_device_id(sensor_hal_t *hal, sensor_data_t *data)
{
	uint8_t const part_id = sensor_bus_get(hal, SFH7770_PART_ID);

	data->device.id = (uint32_t)(part_id & PART_ID_MASK) >> PART_ID_SHIFT;
	data->device.version = (uint32_t)(part_id & PART_REV_MASK);

	return true;
}
Example #28
0
int nvram_updating(void)
{
       return (nvram_read(NVRAM_RTC_FREQ_SELECT) & NVRAM_RTC_UIP) ? 1 : 0;
}
Example #29
0
static uint8_t NVRAM_get_byte(Nvram *nvram, uint32_t addr)
{
    return nvram_read(nvram, addr);
}
Example #30
0
int env_load(void)
{
    int size;
    unsigned char *buffer;
    unsigned char *ptr;
    unsigned char *envval;
    unsigned int reclen;
    unsigned int rectype;
    int offset;
    int flg;
    int retval = -1;
    char valuestr[256];

    /*
     * If in 'safe mode', don't read the environment the first time.
     */

    if (cfe_startflags & CFE_INIT_SAFE) {
	cfe_startflags &= ~CFE_INIT_SAFE;
	return 0;
	}

    flg = nvram_open();
    if (flg < 0) return flg;

    size = nvram_getsize();
    buffer = KMALLOC(size,0);

    if (buffer == NULL) return CFE_ERR_NOMEM;

    ptr = buffer;
    offset = 0;

    /* Read the record type and length */
    if (nvram_read(ptr,offset,1) != 1) {
	retval = CFE_ERR_IOERR;
	goto error;
	}

    while ((*ptr != ENV_TLV_TYPE_END)  && (size > 1)) {

	/* Adjust pointer for TLV type */
	rectype = *(ptr);
	offset++;
	size--;

	/* 
	 * Read the length.  It can be either 1 or 2 bytes
	 * depending on the code 
	 */
	if (rectype & ENV_LENGTH_8BITS) {
	    /* Read the record type and length - 8 bits */
	    if (nvram_read(ptr,offset,1) != 1) {
		retval = CFE_ERR_IOERR;
		goto error;
		}
	    reclen = *(ptr);
	    size--;
	    offset++;
	    }
	else {
	    /* Read the record type and length - 16 bits, MSB first */
	    if (nvram_read(ptr,offset,2) != 2) {
		retval = CFE_ERR_IOERR;
		goto error;
		}
	    reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1);
	    size -= 2;
	    offset += 2;
	    }

	if (reclen > size) break;	/* should not happen, bad NVRAM */

	switch (rectype) {
	    case ENV_TLV_TYPE_ENV:
		/* Read the TLV data */
		if (nvram_read(ptr,offset,reclen) != reclen) goto error;
		flg = *ptr++;
		envval = (unsigned char *) strnchr(ptr,'=',(reclen-1));
		if (envval) {
		    *envval++ = '\0';
		    memcpy(valuestr,envval,(reclen-1)-(envval-ptr));
		    valuestr[(reclen-1)-(envval-ptr)] = '\0';
		    env_setenv(ptr,valuestr,flg);
		    }
		break;
		
	    default: 
		/* Unknown TLV type, skip it. */
		break;
	    }

	/*
	 * Advance to next TLV 
	 */
		
	size -= (int)reclen;
	offset += reclen;

	/* Read the next record type */
	ptr = buffer;
	if (nvram_read(ptr,offset,1) != 1) goto error;
	}

    retval = 0;		/* success! */

error:
    KFREE(buffer);
    nvram_close();

    return retval;

}