Project 2 - Design and develop the web based Temperature control system using Beagle Bone Black.
1. **Device Tree Source (DTS) File** (`am335x-boneblack.dts`):
/dts-v1/;
/plugin/;
/ {
compatible = "ti,am335x-bone-black";
fragment@0 {
target = <&ocp>;
__overlay__ {
mcp9808: mcp9808@18 {
compatible = "microchip,mcp9808";
reg = <0x18>;
interrupt-parent = <&gpio3>;
interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
};
};
};
};
2. **Platform Module Driver for MCP9808** (`drivers/misc/mcp9808.c`):
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/interrupt.h>
#define DRIVER_NAME "mcp9808"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
static struct i2c_client *client;
static int temp_threshold = 30; // Initial threshold temperature
static irqreturn_t mcp9808_irq_handler(int irq, void *dev_id)
{
int temperature;
// Read temperature from sensor
// If temperature exceeds threshold, turn on motor
// Otherwise, turn off motor
}
static int mcp9808_read_temperature(void)
{
// Read temperature from sensor via I2C
// Return temperature value
}
static ssize_t mcp9808_read(struct file *filp, char __user *buf, size_t count, loff_t *offset)
{
int temperature = mcp9808_read_temperature();
if (temperature < 0)
return temperature;
if (copy_to_user(buf, &temperature, sizeof(temperature)))
return -EFAULT;
return sizeof(temperature);
}
static ssize_t mcp9808_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset)
{
// Implementation of writing threshold temperature to sensor
}
static const struct file_operations mcp9808_fops = {
.owner = THIS_MODULE,
.read = mcp9808_read,
.write = mcp9808_write,
};
static struct miscdevice mcp9808_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DRIVER_NAME,
.fops = &mcp9808_fops,
};
static int mcp9808_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{
int ret;
// Initialize the I2C client
client = cl;
// Register the misc device
ret = misc_register(&mcp9808_miscdev);
if (ret) {
dev_err(&cl->dev, "Failed to register misc device\n");
return ret;
}
// Register the interrupt handler for temperature alert pin
ret = request_irq(gpio_to_irq(19), mcp9808_irq_handler, IRQF_TRIGGER_FALLING, "mcp9808", NULL);
if (ret) {
dev_err(&cl->dev, "Failed to register IRQ for temperature alert\n");
misc_deregister(&mcp9808_miscdev);
return ret;
}
pr_info("MCP9808 driver initialized\n");
return 0;
}
static int mcp9808_remove(struct i2c_client *cl)
{
misc_deregister(&mcp9808_miscdev);
free_irq(gpio_to_irq(19), NULL);
pr_info("MCP9808 driver removed\n");
return 0;
}
static const struct i2c_device_id mcp9808_id[] = {
{ "mcp9808", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, mcp9808_id);
static struct i2c_driver mcp9808_driver = {
.driver = {
.name = "mcp9808",
},
.probe = mcp9808_probe,
.remove = mcp9808_remove,
.id_table = mcp9808_id,
};
module_i2c_driver(mcp9808_driver);