diff --git a/11-InterruptsHandling/Makefile b/11-InterruptsHandling/Makefile new file mode 100644 index 0000000..3864102 --- /dev/null +++ b/11-InterruptsHandling/Makefile @@ -0,0 +1,41 @@ +NAME = mpu6050 + +ifneq ($(KERNELRELEASE),) + +obj-m := $(NAME).o + +else + +NAMELINUX ?= root@192.168.0.130 +MODULEDIR ?= /lib/modules/4.19.83-sunxi/kernel/drivers/iio/accel +KERNELDIR ?= /home/dmitry/GL/orange-pi-4.19.83 +DTSDIR ?= $(PWD)/dtsi + +export ARCH = arm +export CROSS_COMPILE ?= arm-linux-gnueabihf- + +.PHONY: all clean + +all: $(NAME).c + $(MAKE) -C $(KERNELDIR) M=$(CURDIR) modules + +dtbo: + $(KERNELDIR)/scripts/dtc/dtc -I dts -O dtb \ + -o $(DTSDIR)/$(NAME).dtbo \ + $(DTSDIR)/$(NAME).dtsi + +copymod: $(NAME).ko + scp $< $(NAMELINUX):$(MODULEDIR) + +copysshid: + ssh-copy-id -i ~/.ssh/id_rsa.pub $(NAMELINUX) + +copydtbo: + scp $(PWD)/dtsi/$(NAME).dtbo \ + $(NAMELINUX):/boot/overlay-user + +clean: + $(MAKE) -C $(KERNELDIR) M=$(CURDIR) clean + -rm $(DTSDIR)/$(NAME).dtbo + +endif diff --git a/11-InterruptsHandling/README.md b/11-InterruptsHandling/README.md new file mode 100644 index 0000000..7b7bff7 --- /dev/null +++ b/11-InterruptsHandling/README.md @@ -0,0 +1,23 @@ +# Interrupts handling + +## Homework + +**(based on MPU6050 driver)** + +1. Setup handling of MPU6050 interrupts. +- Configure interrupt request on MPU6050 (e.g. motion detection). +- Connect interrupt output of the MPU6050 with Orange-Pi GPIO. +- Configure GPIO as input. +- Register handler for the MPU6050 interrupt. + +2. Implement deferred interrupt handler (e.g. in custom workqueue) to handle the request. +- Read new measurements. +- Implement measurements processing (e.g. the following or per your preference). + - filtering (e.g. moving average); + - integrating (for acc to get speed); + - determine trends; + - etc. + +3. Provide additional interface (e.g. in procfs) to read the processed data at once. + +_Note: Remember to synchronize all concurrent operations_ diff --git a/11-InterruptsHandling/dtsi/mpu6050.dtsi b/11-InterruptsHandling/dtsi/mpu6050.dtsi new file mode 100644 index 0000000..bf3f107 --- /dev/null +++ b/11-InterruptsHandling/dtsi/mpu6050.dtsi @@ -0,0 +1,43 @@ +/dts-v1/; +/plugin/; + +//IRQ_TYPE_EDGE_RISING = 1 +//IRQ_TYPE_EDGE_FALLING = 2 +//IRQ_TYPE_LEVEL_HIGH = 4 +//IRQ_TYPE_LEVEL_LOW = 8 + +//GIC_SPI = 0 +//GIC_PPI = 1 + +/ { + compatible = "allwinner,sun8i-h3"; + + fragment@0 { + target = <&pio>; + __overlay__ { + mpu6050_int: pin_int { + pins = "PA6"; + function = "gpio_in"; + }; + }; + }; + + fragment@1 { + target = <&i2c0>; + __overlay__ { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + mpu: mpu6050@68 { + compatible = "gl, mpu6050"; + pinctrl-names = "default"; + reg = <0x68>; + pinctrl-0 = <&mpu6050_int>; + interrupt-parent = <&pio>; + interrupts = <0 6 2>; // PA6 + status = "okay"; + }; + }; + }; +}; diff --git a/11-InterruptsHandling/mpu6050-regs.h b/11-InterruptsHandling/mpu6050-regs.h new file mode 100644 index 0000000..b03826d --- /dev/null +++ b/11-InterruptsHandling/mpu6050-regs.h @@ -0,0 +1,42 @@ +#ifndef _MPU6050_REGS_H +#define _MPU6050_REGS_H + +/* Registed addresses */ +#define REG_CONFIG 0x1A +#define REG_GYRO_CONFIG 0x1B +#define REG_ACCEL_CONFIG 0x1C +#define REG_FF_THR 0x1D +#define REG_FF_DUR 0x1E +#define REG_MOT_THR 0x1F +#define REG_MOT_DUR 0x20 +#define REG_ZRMOT_THR 0x21 +#define REG_ZRMOT_DUR 0x22 +#define REG_FIFO_EN 0x23 +#define REG_SMPRT_DIV 0x25 +#define REG_INT_PIN_CFG 0x37 +#define REG_INT_ENABLE 0x38 +#define REG_INT_STATUS 0x3A +#define REG_ACCEL_XOUT_H 0x3B +#define REG_ACCEL_XOUT_L 0x3C +#define REG_ACCEL_YOUT_H 0x3D +#define REG_ACCEL_YOUT_L 0x3E +#define REG_ACCEL_ZOUT_H 0x3F +#define REG_ACCEL_ZOUT_L 0x40 +#define REG_TEMP_OUT_H 0x41 +#define REG_TEMP_OUT_L 0x42 +#define REG_GYRO_XOUT_H 0x43 +#define REG_GYRO_XOUT_L 0x44 +#define REG_GYRO_YOUT_H 0x45 +#define REG_GYRO_YOUT_L 0x46 +#define REG_GYRO_ZOUT_H 0x47 +#define REG_GYRO_ZOUT_L 0x48 +#define REG_USER_CTRL 0x6A +#define REG_PWR_MGMT_1 0x6B +#define REG_PWR_MGMT_2 0x6C +#define REG_WHO_AM_I 0x75 +#define REG_MOT_DETECT_STATUS 0x97 + +/* Register values */ +#define MPU6050_WHO_AM_I 0x68 + +#endif /* _MPU6050_REGS_H */ diff --git a/11-InterruptsHandling/mpu6050.c b/11-InterruptsHandling/mpu6050.c new file mode 100644 index 0000000..e1e929a --- /dev/null +++ b/11-InterruptsHandling/mpu6050.c @@ -0,0 +1,408 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mpu6050-regs.h" + +struct temp_t { + int temp; + int t_int; + int t_frac; +}; + +struct mpu6050_data { + struct i2c_client *drv_client; + int accel_values[3]; + int gyro_values[3]; + struct temp_t temperature; + struct mutex mutex_mpu; + int avr_acc_x[10], avr_acc_y[10], avr_acc_z[10]; + int avr_gyro_x[10], avr_gyro_y[10], avr_gyro_z[10]; + int avr_temp[10]; +}; + +static struct mpu6050_data g_mpu6050_data; + +static int mpu6050_read_data(void) +{ + int ret = 0, i = 0; + long val[7] = {0}; + struct i2c_client *drv_client = g_mpu6050_data.drv_client; + + if (drv_client == 0) + return -ENODEV; + + // Disable INT + if (IS_ERR_VALUE(i2c_smbus_write_byte_data(drv_client, + REG_INT_ENABLE, 0x00))) { + dev_err(&drv_client->dev, + "i2c_smbus_write_byte_data() failed\n"); + return -EIO; + } + + ret = i2c_smbus_read_byte_data(drv_client, REG_INT_STATUS); + if (IS_ERR_VALUE(ret)) { + dev_err(&drv_client->dev, + "i2c_smbus_read_byte_data() failed\n"); + return -EIO; + } + dev_info(&drv_client->dev, "REG_INT_STATUS: 0x%x\n", ret); + + if (ret & 0x40) { + for (i = 0; i < 10; i++) { + if (i == 9) { + /* accel */ + g_mpu6050_data.avr_acc_x[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_ACCEL_XOUT_H)); + g_mpu6050_data.avr_acc_y[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_ACCEL_YOUT_H)); + g_mpu6050_data.avr_acc_z[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_ACCEL_ZOUT_H)); + /* gyro */ + g_mpu6050_data.avr_gyro_x[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_GYRO_XOUT_H)); + g_mpu6050_data.avr_gyro_y[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_GYRO_YOUT_H)); + g_mpu6050_data.avr_gyro_z[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_GYRO_ZOUT_H)); + /* temp */ + g_mpu6050_data.avr_temp[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_TEMP_OUT_H)); + } else { + g_mpu6050_data.avr_acc_x[i] = g_mpu6050_data.avr_acc_x[i+1]; + g_mpu6050_data.avr_acc_y[i] = g_mpu6050_data.avr_acc_y[i+1]; + g_mpu6050_data.avr_acc_z[i] = g_mpu6050_data.avr_acc_z[i+1]; + g_mpu6050_data.avr_gyro_x[i] = g_mpu6050_data.avr_gyro_x[i+1]; + g_mpu6050_data.avr_gyro_y[i] = g_mpu6050_data.avr_gyro_y[i+1]; + g_mpu6050_data.avr_gyro_z[i] = g_mpu6050_data.avr_gyro_z[i+1]; + g_mpu6050_data.avr_temp[i] = g_mpu6050_data.avr_temp[i+1]; + } + msleep(1); + } + for (i = 0; i < 10; i++) { + val[0] += g_mpu6050_data.avr_acc_x[i]; + val[1] += g_mpu6050_data.avr_acc_y[i]; + val[2] += g_mpu6050_data.avr_acc_z[i]; + val[3] += g_mpu6050_data.avr_gyro_x[i]; + val[4] += g_mpu6050_data.avr_gyro_y[i]; + val[5] += g_mpu6050_data.avr_gyro_z[i]; + val[6] += g_mpu6050_data.avr_temp[i]; + } + g_mpu6050_data.accel_values[0] = val[0] / 10; + g_mpu6050_data.accel_values[1] = val[1] / 10; + g_mpu6050_data.accel_values[2] = val[2] / 10; + g_mpu6050_data.gyro_values[0] = val[3] / 10; + g_mpu6050_data.gyro_values[1] = val[4] / 10; + g_mpu6050_data.gyro_values[2] = val[5] / 10; + g_mpu6050_data.temperature.temp = val[6] / 10; + + g_mpu6050_data.temperature.t_int = (g_mpu6050_data.temperature.temp * 1000 / 340 + 35000) / 1000; + g_mpu6050_data.temperature.t_frac = (g_mpu6050_data.temperature.temp * 1000 / 340 + 35000) % 1000; + + dev_info(&drv_client->dev, "sensor data read:\n"); + dev_info(&drv_client->dev, "ACCEL[X,Y,Z] = [%d, %d, %d]\n", + g_mpu6050_data.accel_values[0], + g_mpu6050_data.accel_values[1], + g_mpu6050_data.accel_values[2]); + dev_info(&drv_client->dev, "GYRO[X,Y,Z] = [%d, %d, %d]\n", + g_mpu6050_data.gyro_values[0], + g_mpu6050_data.gyro_values[1], + g_mpu6050_data.gyro_values[2]); + dev_info(&drv_client->dev, "TEMP = %02d.%03d\n", + g_mpu6050_data.temperature.t_int, + g_mpu6050_data.temperature.t_frac); + } + + // Enable INT + if (IS_ERR_VALUE(i2c_smbus_write_byte_data(drv_client, + REG_INT_ENABLE, 0x40))) { + dev_err(&drv_client->dev, + "i2c_smbus_write_byte_data() failed\n"); + return -EIO; + } + + return 0; +} + +static irqreturn_t interrupt_handler(int irq, void *dev_id) +{ + dev_info(&((struct mpu6050_data *)dev_id)->drv_client->dev, + "**************** Interrupt generated #%d ****************", + ((struct mpu6050_data *)dev_id)->drv_client->irq); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t interrupt_thread(int irq, void *dev_id) +{ + mutex_lock(&((struct mpu6050_data *)dev_id)->mutex_mpu); + mpu6050_read_data(); + mutex_unlock(&((struct mpu6050_data *)dev_id)->mutex_mpu); + + return IRQ_HANDLED; +} + +static ssize_t accel_x_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + mutex_lock(&g_mpu6050_data.mutex_mpu); + sprintf(buf, "%d\n", g_mpu6050_data.accel_values[0]); + mutex_unlock(&g_mpu6050_data.mutex_mpu); + + return strlen(buf); +} + +static ssize_t accel_y_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + mutex_lock(&g_mpu6050_data.mutex_mpu); + sprintf(buf, "%d\n", g_mpu6050_data.accel_values[1]); + mutex_unlock(&g_mpu6050_data.mutex_mpu); + + return strlen(buf); +} + +static ssize_t accel_z_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + mutex_lock(&g_mpu6050_data.mutex_mpu); + sprintf(buf, "%d\n", g_mpu6050_data.accel_values[2]); + mutex_unlock(&g_mpu6050_data.mutex_mpu); + + return strlen(buf); +} + +static ssize_t gyro_x_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + mutex_lock(&g_mpu6050_data.mutex_mpu); + sprintf(buf, "%d\n", g_mpu6050_data.gyro_values[0]); + mutex_unlock(&g_mpu6050_data.mutex_mpu); + + return strlen(buf); +} + +static ssize_t gyro_y_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + mutex_lock(&g_mpu6050_data.mutex_mpu); + sprintf(buf, "%d\n", g_mpu6050_data.gyro_values[1]); + mutex_unlock(&g_mpu6050_data.mutex_mpu); + + return strlen(buf); +} + +static ssize_t gyro_z_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + mutex_lock(&g_mpu6050_data.mutex_mpu); + sprintf(buf, "%d\n", g_mpu6050_data.gyro_values[2]); + mutex_unlock(&g_mpu6050_data.mutex_mpu); + + return strlen(buf); +} + +static ssize_t temp_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + mutex_lock(&g_mpu6050_data.mutex_mpu); + sprintf(buf, "%02d.%03d\n", g_mpu6050_data.temperature.t_int, + g_mpu6050_data.temperature.t_frac); + mutex_unlock(&g_mpu6050_data.mutex_mpu); + + return strlen(buf); +} + +CLASS_ATTR_RO(accel_x); +CLASS_ATTR_RO(accel_y); +CLASS_ATTR_RO(accel_z); +CLASS_ATTR_RO(gyro_x); +CLASS_ATTR_RO(gyro_y); +CLASS_ATTR_RO(gyro_z); +CLASS_ATTR_RO(temp); + +static struct attribute *mpu_class_attrs[] = { + &class_attr_accel_x.attr, + &class_attr_accel_y.attr, + &class_attr_accel_z.attr, + &class_attr_gyro_x.attr, + &class_attr_gyro_y.attr, + &class_attr_gyro_z.attr, + &class_attr_temp.attr, + NULL, +}; + +ATTRIBUTE_GROUPS(mpu_class); + +/* Device model classes */ +struct class mpu_rc_class = { + .name = "mpu6050", + .owner = THIS_MODULE, + .class_groups = mpu_class_groups, +}; + +static int mpu6050_probe(struct i2c_client *drv_client, + const struct i2c_device_id *id) +{ + int ret = 0, i = 0; + + mutex_init(&g_mpu6050_data.mutex_mpu); + + dev_info(&drv_client->dev, + "i2c client address is 0x%X\n", drv_client->addr); + + /* Read who_am_i register */ + ret = i2c_smbus_read_byte_data(drv_client, REG_WHO_AM_I); + if (IS_ERR_VALUE(ret)) { + dev_err(&drv_client->dev, + "i2c_smbus_read_byte_data() failed\n"); + return -EIO; + } + if (ret != MPU6050_WHO_AM_I) { + dev_err(&drv_client->dev, + "wrong i2c device found: expected 0x%X, found 0x%X\n", + MPU6050_WHO_AM_I, ret); + return -ENODEV; + } + dev_info(&drv_client->dev, + "i2c mpu6050 device found, WHO_AM_I register value = 0x%X\n", + ret); + + /* Setup the device */ + // reset + if (IS_ERR_VALUE(i2c_smbus_write_byte_data(drv_client, + REG_PWR_MGMT_1, 0x80))) { + dev_err(&drv_client->dev, + "i2c_smbus_write_byte_data() failed\n"); + return -EIO; + } + + msleep(100); + + // start + if (IS_ERR_VALUE(i2c_smbus_write_byte_data(drv_client, + REG_PWR_MGMT_1, 0x00))) { + dev_err(&drv_client->dev, + "i2c_smbus_write_byte_data() failed\n"); + return -EIO; + } + if (IS_ERR_VALUE(i2c_smbus_write_byte_data(drv_client, + REG_CONFIG, 0x03))) { + dev_err(&drv_client->dev, + "i2c_smbus_write_byte_data() failed\n"); + return -EIO; + } + if (IS_ERR_VALUE(i2c_smbus_write_byte_data(drv_client, + REG_SMPRT_DIV, 0x04))) { + dev_err(&drv_client->dev, + "i2c_smbus_write_byte_data() failed\n"); + return -EIO; + } + if (IS_ERR_VALUE(i2c_smbus_write_byte_data(drv_client, + REG_MOT_THR, 0x15))) { + dev_err(&drv_client->dev, + "i2c_smbus_write_byte_data() failed\n"); + return -EIO; + } + if (IS_ERR_VALUE(i2c_smbus_write_byte_data(drv_client, + REG_MOT_DUR, 0x02))) { + dev_err(&drv_client->dev, + "i2c_smbus_write_byte_data() failed\n"); + return -EIO; + } + if (IS_ERR_VALUE(i2c_smbus_write_byte_data(drv_client, + REG_INT_PIN_CFG, 0xB2))) { + dev_err(&drv_client->dev, + "i2c_smbus_write_byte_data() failed\n"); + return -EIO; + } + if (IS_ERR_VALUE(i2c_smbus_write_byte_data(drv_client, + REG_INT_ENABLE, 0x40))) { + dev_err(&drv_client->dev, + "i2c_smbus_write_byte_data() failed\n"); + return -EIO; + } + + ret = request_threaded_irq(drv_client->irq, interrupt_handler, + interrupt_thread, IRQF_ONESHOT | IRQF_TRIGGER_FALLING, + "mpu6050", (void *)&g_mpu6050_data); + if (ret) { + dev_err(&drv_client->dev, + "error irq , unable to request IRQ#%d: %d\n", + drv_client->irq, ret); + return ret; + } + + dev_info(&drv_client->dev, "IRQ #%d\n", drv_client->irq); + + ret = class_register(&mpu_rc_class); + if (ret < 0) { + dev_err(&drv_client->dev, "failed to create sysfs class: %d\n", + ret); + return ret; + } + dev_info(&drv_client->dev, "sysfs class created\n"); + + // Read data for update + for (i = 0; i < 10; i++) { + /* accel */ + g_mpu6050_data.avr_acc_x[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_ACCEL_XOUT_H)); + g_mpu6050_data.avr_acc_y[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_ACCEL_YOUT_H)); + g_mpu6050_data.avr_acc_z[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_ACCEL_ZOUT_H)); + /* gyro */ + g_mpu6050_data.avr_gyro_x[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_GYRO_XOUT_H)); + g_mpu6050_data.avr_gyro_y[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_GYRO_YOUT_H)); + g_mpu6050_data.avr_gyro_z[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_GYRO_ZOUT_H)); + /* temp */ + g_mpu6050_data.avr_temp[i] = (s16)((u16)i2c_smbus_read_word_swapped(drv_client, REG_TEMP_OUT_H)); + } + + g_mpu6050_data.drv_client = drv_client; + + dev_info(&drv_client->dev, "i2c driver probed\n"); + return 0; +} + +static int mpu6050_remove(struct i2c_client *drv_client) +{ + g_mpu6050_data.drv_client = 0; + + class_unregister(&mpu_rc_class); + dev_info(&drv_client->dev, "sysfs class destroyed\n"); + + free_irq(drv_client->irq, (void *)&g_mpu6050_data); + + mutex_destroy(&g_mpu6050_data.mutex_mpu); + + dev_info(&drv_client->dev, "i2c driver removed\n"); + return 0; +} + +static const struct of_device_id mpu6050_ids[] = { + { .compatible = "gl, mpu6050", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, mpu6050_ids); + +static const struct i2c_device_id mpu6050_idtable[] = { + { "mpu6050", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mpu6050_idtable); + +static struct i2c_driver mpu6050_i2c_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "mpu6050", + .of_match_table = of_match_ptr(mpu6050_ids), + }, + .probe = mpu6050_probe, + .remove = mpu6050_remove, + .id_table = mpu6050_idtable, +}; + +module_i2c_driver(mpu6050_i2c_driver); + +MODULE_AUTHOR("Dmitry Domnin"); +MODULE_DESCRIPTION("mpu6050 I2C acc&gyro interrupt"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1"); diff --git a/11-InterruptsHandling/result/attributes.txt b/11-InterruptsHandling/result/attributes.txt new file mode 100644 index 0000000..11d19da --- /dev/null +++ b/11-InterruptsHandling/result/attributes.txt @@ -0,0 +1,17 @@ +root@orangepione:~# ls /sys/class/mpu6050/ +accel_x accel_y accel_z gyro_x gyro_y gyro_z temp +root@orangepione:~# cat /sys/class/mpu6050/accel_x +2036 +root@orangepione:~# cat /sys/class/mpu6050/accel_y +-14047 +root@orangepione:~# cat /sys/class/mpu6050/accel_z +-5739 +root@orangepione:~# cat /sys/class/mpu6050/gyro_x +2490 +root@orangepione:~# cat /sys/class/mpu6050/gyro_y +-2510 +root@orangepione:~# cat /sys/class/mpu6050/gyro_z +-1096 +root@orangepione:~# cat /sys/class/mpu6050/temp +25.589 + diff --git a/11-InterruptsHandling/result/dmesg.txt b/11-InterruptsHandling/result/dmesg.txt new file mode 100644 index 0000000..3a30e4c --- /dev/null +++ b/11-InterruptsHandling/result/dmesg.txt @@ -0,0 +1,43 @@ +root@orangepione:~# dmesg -w +[ 6870.064098] mpu6050 0-0068: i2c client address is 0x68 +[ 6870.064616] mpu6050 0-0068: i2c mpu6050 device found, WHO_AM_I register value = 0x68 +[ 6870.174775] mpu6050 0-0068: IRQ #56 +[ 6870.174950] mpu6050 0-0068: sysfs class created +[ 6870.211718] mpu6050 0-0068: i2c driver probed +[ 6872.690036] mpu6050 0-0068: **************** Interrupt generated #56 **************** +[ 6872.690930] mpu6050 0-0068: REG_INT_STATUS: 0x41 +[ 6872.808304] mpu6050 0-0068: sensor data read: +[ 6872.808322] mpu6050 0-0068: ACCEL[X,Y,Z] = [1319, -14019, -472] +[ 6872.808334] mpu6050 0-0068: GYRO[X,Y,Z] = [1780, -2086, -905] +[ 6872.808347] mpu6050 0-0068: TEMP = 25.806 +[ 6878.541825] mpu6050 0-0068: **************** Interrupt generated #56 **************** +[ 6878.542785] mpu6050 0-0068: REG_INT_STATUS: 0x41 +[ 6878.660497] mpu6050 0-0068: sensor data read: +[ 6878.660517] mpu6050 0-0068: ACCEL[X,Y,Z] = [1452, -15085, -1304] +[ 6878.660530] mpu6050 0-0068: GYRO[X,Y,Z] = [2034, -2832, -1004] +[ 6878.660543] mpu6050 0-0068: TEMP = 25.612 +[ 6884.887330] mpu6050 0-0068: **************** Interrupt generated #56 **************** +[ 6884.888278] mpu6050 0-0068: REG_INT_STATUS: 0x41 +[ 6885.004710] mpu6050 0-0068: sensor data read: +[ 6885.004731] mpu6050 0-0068: ACCEL[X,Y,Z] = [1729, -15289, -2335] +[ 6885.004743] mpu6050 0-0068: GYRO[X,Y,Z] = [-375, -4567, -2476] +[ 6885.004756] mpu6050 0-0068: TEMP = 25.553 +[ 7341.633744] mpu6050 0-0068: **************** Interrupt generated #56 **************** +[ 7341.634602] mpu6050 0-0068: REG_INT_STATUS: 0x41 +[ 7341.752150] mpu6050 0-0068: sensor data read: +[ 7341.752171] mpu6050 0-0068: ACCEL[X,Y,Z] = [1876, -15059, -3349] +[ 7341.752184] mpu6050 0-0068: GYRO[X,Y,Z] = [1046, -3483, -1966] +[ 7341.752197] mpu6050 0-0068: TEMP = 25.542 +[ 7759.849566] mpu6050 0-0068: **************** Interrupt generated #56 **************** +[ 7759.850467] mpu6050 0-0068: REG_INT_STATUS: 0x41 +[ 7759.970265] mpu6050 0-0068: sensor data read: +[ 7759.970286] mpu6050 0-0068: ACCEL[X,Y,Z] = [2178, -14814, -4430] +[ 7759.970300] mpu6050 0-0068: GYRO[X,Y,Z] = [2615, -2274, -1317] +[ 7759.970312] mpu6050 0-0068: TEMP = 25.559 +[ 7760.701040] mpu6050 0-0068: **************** Interrupt generated #56 **************** +[ 7760.701894] mpu6050 0-0068: REG_INT_STATUS: 0x41 +[ 7760.818290] mpu6050 0-0068: sensor data read: +[ 7760.818309] mpu6050 0-0068: ACCEL[X,Y,Z] = [2036, -14047, -5739] +[ 7760.818322] mpu6050 0-0068: GYRO[X,Y,Z] = [2490, -2510, -1096] +[ 7760.818334] mpu6050 0-0068: TEMP = 25.589 + diff --git a/11-InterruptsHandling/result/start-uboot.txt b/11-InterruptsHandling/result/start-uboot.txt new file mode 100644 index 0000000..2028a99 --- /dev/null +++ b/11-InterruptsHandling/result/start-uboot.txt @@ -0,0 +1,90 @@ +U-Boot SPL 2019.04-armbian (Dec 01 2019 - 12:47:04 +0200) +DRAM: 512 MiB +Trying to boot from MMC1 + + +U-Boot 2019.04-armbian (Dec 01 2019 - 12:47:04 +0200) Allwinner Technology + +CPU: Allwinner H3 (SUN8I 1680) +Model: Xunlong Orange Pi One +DRAM: 512 MiB +MMC: mmc@1c0f000: 0 +Loading Environment from EXT4... ** File not found /boot/boot.env ** + +** Unable to read "/boot/boot.env" from mmc0:1 ** +In: serial +Out: serial +Err: serial +Net: phy interface0 +eth0: ethernet@1c30000 +** Reading file would overwrite reserved memory ** +There is no valid bmp file at the given address +starting USB... +USB0: USB EHCI 1.00 +USB1: USB OHCI 1.0 +USB2: USB EHCI 1.00 +USB3: USB OHCI 1.0 +scanning bus 0 for devices... 1 USB Device(s) found +scanning bus 1 for devices... 1 USB Device(s) found +scanning bus 2 for devices... 1 USB Device(s) found +scanning bus 3 for devices... 1 USB Device(s) found + scanning usb for storage devices... 0 Storage Device(s) found +Autoboot in 1 seconds, press to stop +switch to partitions #0, OK +mmc0 is current device +Scanning mmc 0:1... +Found U-Boot script /boot/boot.scr +3798 bytes read in 2 ms (1.8 MiB/s) +## Executing script at 43100000 +U-boot loaded from SD +Boot script loaded from mmc +251 bytes read in 2 ms (122.1 KiB/s) +6842649 bytes read in 332 ms (19.7 MiB/s) +7430672 bytes read in 360 ms (19.7 MiB/s) +Found mainline kernel configuration +29878 bytes read in 10 ms (2.8 MiB/s) +374 bytes read in 8 ms (44.9 KiB/s) +Applying kernel provided DT overlay sun8i-h3-i2c0.dtbo +274 bytes read in 3 ms (88.9 KiB/s) +Applying user provided DT overlay fake_module.dtbo +879 bytes read in 3 ms (286.1 KiB/s) +Applying user provided DT overlay mpu6050.dtbo +4155 bytes read in 4 ms (1013.7 KiB/s) +Applying kernel provided DT fixup script (sun8i-h3-fixup.scr) +## Executing script at 44000000 +## Loading init Ramdisk from Legacy Image at 43300000 ... + Image Name: uInitrd + Image Type: ARM Linux RAMDisk Image (gzip compressed) + Data Size: 6842585 Bytes = 6.5 MiB + Load Address: 00000000 + Entry Point: 00000000 + Verifying Checksum ... OK +## Flattened Device Tree blob at 43000000 + Booting using the fdt blob at 0x43000000 +EHCI failed to shut down host controller. + Loading Ramdisk to 49979000, end 49fff8d9 ... OK + Loading Device Tree to 49909000, end 49978fff ... OK + +Starting kernel ... + +Uncompressing Linux... done, booting the kernel. +Loading, please wait... +Starting version 241 +Begin: Loading essential drivers ... done. +Begin: Running /scripts/init-premount ... done. +Begin: Mounting root file system ... Begin: Running /scripts/local-top ... done. +Begin: Running /scripts/local-premount ... Scanning for Btrfs filesystems +done. +Begin: Will now check root file system ... fsck from util-linux 2.33.1 +[/sbin/fsck.ext4 (1) -- /dev/mmcblk0p1] fsck.ext4 -a -C0 /dev/mmcblk0p1 +/dev/mmcblk0p1: clean, 37593/228928 files, 294183/912384 blocks +done. +done. +Begin: Running /scripts/local-bottom ... done. +Begin: Running /scripts/init-bottom ... done. + +Welcome to Debian GNU/Linux 10 (buster)! + +[ OK ] Reached target Swap. +[ OK ] Listening on Journal Socket. +[ OK ] Created slice system-getty.slice.