I want to apologize, I thought that nobody interested in my modification, because the topic is stalled.
If I make a patch file be enough?
--- w1/w1.h 2016-07-02 20:09:37.000000000 +0500
+++ w1.mod/w1.h 2016-06-12 19:36:58.000000000 +0500
@@ -52,6 +52,7 @@
#define W1_CONVERT_TEMP 0x44
#define W1_SKIP_ROM 0xCC
#define W1_READ_SCRATCHPAD 0xBE
+#define W1_WRITE_SCRATCHPAD 0x4E
#define W1_READ_ROM 0x33
#define W1_READ_PSUPPLY 0xB4
#define W1_MATCH_ROM 0x55
--- w1/w1_io.c 2016-07-02 20:09:37.000000000 +0500
+++ w1.mod/w1_io.c 2016-06-12 19:43:12.000000000 +0500
@@ -73,18 +73,18 @@
}
}
-/**
+/*
* Generates a write-0 or write-1 cycle.
* Only call if dev->bus_master->touch_bit is NULL
*/
static void w1_write_bit(struct w1_master *dev, int bit)
{
- if (bit) {
+ if (bit) { // write 1
dev->bus_master->write_bit(dev->bus_master->data, 0);
- w1_delay(6);
+ w1_delay(5);
dev->bus_master->write_bit(dev->bus_master->data, 1);
- w1_delay(64);
- } else {
+ w1_delay(55);
+ } else { // write 0
dev->bus_master->write_bit(dev->bus_master->data, 0);
w1_delay(60);
dev->bus_master->write_bit(dev->bus_master->data, 1);
@@ -136,6 +136,11 @@
{
int i;
+ /* EK45 (add from datasheet)
+ The DS18B20 samples the 1-Wire bus during a window that lasts from 15µs to 60µs after the master
+ initiates the write time slot. If the bus is high during the sampling window, a 1 is written to the DS18B20.
+ If the line is low, a 0 is written to the DS18B20
+ */
if (dev->bus_master->write_byte) {
w1_pre_write(dev);
dev->bus_master->write_byte(dev->bus_master->data, byte);
@@ -161,16 +166,24 @@
unsigned long flags;
/* sample timing is critical here */
+ /* EK45 add from datasheet
+ All read time slots must be a minimum of 60µs in duration with a minimum of a 1µs recovery time
+ between slots. A read time slot is initiated by the master device pulling the 1-Wire bus low for a
+ minimum of 1µs and then releasing the bus (see Figure 14). After the master initiates the read time slot,
+ the DS18B20 will begin transmitting a 1 or 0 on bus. The DS18B20 transmits a 1 by leaving the bus high
+ and transmits a 0 by pulling the bus low. When transmitting a 0, the DS18B20 will release the bus by the
+ end of the time slot, and the bus will be pulled back to its high idle state by the pullup resister. Output
+ data from the DS18B20 is valid for 15µs after the falling edge that initiated the read time slot. Therefore,
+ the master must release the bus and then sample the bus state within 15µs from the start of the slot.
+ */
local_irq_save(flags);
dev->bus_master->write_bit(dev->bus_master->data, 0);
- w1_delay(6);
+ w1_delay(2);
dev->bus_master->write_bit(dev->bus_master->data, 1);
- w1_delay(9);
-
+ w1_delay(8);
result = dev->bus_master->read_bit(dev->bus_master->data);
local_irq_restore(flags);
-
- w1_delay(55);
+ w1_delay(50);
return result & 0x1;
}
@@ -322,7 +335,6 @@
if (dev->bus_master->reset_bus)
result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1;
else {
- dev->bus_master->write_bit(dev->bus_master->data, 0);
/* minimum 480, max ? us
* be nice and sleep, except 18b20 spec lists 960us maximum,
* so until we can sleep with microsecond accuracy, spin.
@@ -330,17 +342,27 @@
* cpu for such a short amount of time AND get it back in
* the maximum amount of time.
*/
+
+ /* EK45 add from data sheet
+ During the initialization sequence the bus master transmits (TX) the reset pulse
+ by pulling the 1-Wire bus low for a minimum of 480µs.
+ The bus master then releases the bus and goes into receive mode (RX).
+ When the bus is released, the 5kΩ pullup resistor pulls the 1-Wire bus high.
+ When the DS18B20 detects this rising edge, it waits 15µs to 60µs and then transmits
+ a presence pulse by pulling the 1-Wire bus low for 60µs to 240µs
+ */
+ dev->bus_master->write_bit(dev->bus_master->data, 0);
w1_delay(480);
dev->bus_master->write_bit(dev->bus_master->data, 1);
w1_delay(70);
-
result = dev->bus_master->read_bit(dev->bus_master->data) & 0x1;
/* minmum 70 (above) + 410 = 480 us
* There aren't any timing requirements between a reset and
* the following transactions. Sleeping is safe here.
*/
- /* w1_delay(410); min required time */
- msleep(1);
+
+ // EK45 edit 60µs + 240µs = 300µs (max)
+ w1_delay(410); // Rx max len = 480µs from datasheet
}
return result;
--- w1/slaves/w1_therm.c 2016-07-02 20:09:40.000000000 +0500
+++ w1.mod/slaves/w1_therm.c 2016-07-04 15:05:39.167831331 +0500
@@ -2,7 +2,7 @@
* w1_therm.c
*
* Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net>
- *
+ * Resolution modification by Evgeney Kirik <evgeney.kirik@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the therms of the GNU General Public License as published by
@@ -34,35 +34,33 @@
#include "../w1_family.h"
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
+MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net> & EK45 <evgeney.kirik@gmail.com>");
MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family.");
-/* Allow the strong pullup to be disabled, but default to enabled.
- * If it was disabled a parasite powered device might not get the require
- * current to do a temperature conversion. If it is enabled parasite powered
- * devices have a better chance of getting the current required.
- */
-static int w1_strong_pullup = 1;
-module_param_named(strong_pullup, w1_strong_pullup, int, 0);
+//#define W1_WRITE_SCRATCHPAD 0x4E // write scratchpad action byte
-static u8 bad_roms[][9] = {
- {0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 0x10, 0x87},
- {}
- };
+u8 bit_res;
+unsigned int mct[4] = { 95, 190, 375, 750 }; // Max Conversion Time (bit res 9, 10, 11, 12)
-static ssize_t w1_therm_read(struct device *device,
- struct device_attribute *attr, char *buf);
+static ssize_t w1_therm_read(struct device *device, struct device_attribute *attr, char *buf);
+static struct device_attribute w1_therm_attr = __ATTR(w1_slave, S_IRUGO, w1_therm_read, NULL);
-static struct device_attribute w1_therm_attr =
- __ATTR(w1_slave, S_IRUGO, w1_therm_read, NULL);
+static ssize_t w1_resolution_set(struct device *device, struct device_attribute *attr, const char *buf, size_t count);
+static ssize_t w1_resolution_get(struct device *device, struct device_attribute *attr, char *buf);
+static struct device_attribute w1_therm_res = __ATTR(w1_resolution, S_IWUGO | S_IRUGO | S_IWGRP, w1_resolution_get, w1_resolution_set);
static int w1_therm_add_slave(struct w1_slave *sl)
{
- return device_create_file(&sl->dev, &w1_therm_attr);
+ int ret;
+ ret = device_create_file(&sl->dev, &w1_therm_res); // add by EK45
+ ret += device_create_file(&sl->dev, &w1_therm_attr);
+
+ return ret;
}
static void w1_therm_remove_slave(struct w1_slave *sl)
{
+ device_remove_file(&sl->dev, &w1_therm_res); // add by EK45
device_remove_file(&sl->dev, &w1_therm_attr);
}
@@ -159,105 +157,132 @@
return 0;
}
-static int w1_therm_check_rom(u8 rom[9])
+static ssize_t w1_resolution_set(struct device *device, struct device_attribute *attr, const char *buf, size_t count)
{
- int i;
+ struct w1_slave *sl = dev_to_w1_slave(device);
+ struct w1_master *dev = sl->master;
+ u8 scrpad[3];
+
+ if (buf[0] != 0) {
+ bit_res = 0; // 9 bit
+ if (buf[0] == '1') {
+ //dev_warn(device, "Set res to %dbit", bit_res + 9);
+ if (buf[1] == '0') bit_res = 1; // 10 bit
+ if (buf[1] == '1') bit_res = 2; // 11 bit
+ if (buf[1] == '2') bit_res = 3; // 12 bit
+ }
- for (i=0; i<sizeof(bad_roms)/9; ++i)
- if (!memcmp(bad_roms[i], rom, 9))
- return 1;
+ // Write resolution bit to Configuration Register
+ scrpad[2] = (((bit_res & 0x03) << 5) | 0x1F); // set bit res
+ scrpad[1] = 0; // write to eeprom
+ scrpad[0] = scrpad[2]; // write to scratchpad resolution set
+ if (!w1_reset_select_slave(sl)) {
+ w1_write_8(dev, W1_WRITE_SCRATCHPAD);
+ //w1_next_pullup(dev, 10);
+ w1_write_block(dev, scrpad, 3);
+ //dev_warn(device, "ds18x20 set res to %d\n", bit_res);
+ }
+ }
- return 0;
+ return count;
}
-static ssize_t w1_therm_read(struct device *device,
- struct device_attribute *attr, char *buf)
+static ssize_t w1_resolution_get(struct device *device, struct device_attribute *attr, char *buf)
+{
+ struct w1_slave *sl = dev_to_w1_slave(device);
+ struct w1_master *dev = sl->master;
+ u8 rom[9];
+ ssize_t c = PAGE_SIZE;
+
+ bit_res=3; // Read conversion resolution from chip
+ if (!w1_reset_select_slave(sl)) {
+ w1_write_8(dev, W1_READ_SCRATCHPAD);
+ w1_read_block(dev, rom, 9);
+ bit_res = ((rom[4] & 0x60) >> 5);
+ }
+
+ c -= snprintf(buf + PAGE_SIZE - c, c, "%d\n", bit_res + 9);
+
+ return PAGE_SIZE - c;
+}
+
+static ssize_t w1_therm_read(struct device *device, struct device_attribute *attr, char *buf)
{
struct w1_slave *sl = dev_to_w1_slave(device);
struct w1_master *dev = sl->master;
u8 rom[9], crc, verdict, external_power;
- int i, max_trying = 10;
+ int i, max_trying = 5;
ssize_t c = PAGE_SIZE;
i = mutex_lock_interruptible(&dev->mutex);
- if (i != 0)
- return i;
-
- memset(rom, 0, sizeof(rom));
+ if (i != 0) return i;
verdict = 0;
crc = 0;
+ external_power = 1; // if normal power
+ if (!w1_reset_select_slave(sl)) {
+ w1_write_8(dev, W1_READ_PSUPPLY);
+ external_power = w1_read_8(dev);
+
+ }
+
+ bit_res=3; // Read conversion resolution from chip
+ if (!w1_reset_select_slave(sl)) {
+ w1_write_8(dev, W1_READ_SCRATCHPAD);
+ w1_read_block(dev, rom, 9);
+ bit_res = ((rom[4] & 0x60) >> 5);
+ }
+
while (max_trying--) {
if (!w1_reset_select_slave(sl)) {
int count = 0;
- unsigned int tm = 750;
+ unsigned int tms = mct[bit_res]; // set timeout for xbit conversion
unsigned long sleep_rem;
- w1_write_8(dev, W1_READ_PSUPPLY);
- external_power = w1_read_8(dev);
-
- if (w1_reset_select_slave(sl))
- continue;
-
- /* 750ms strong pullup (or delay) after the convert */
- if (!external_power && w1_strong_pullup)
- w1_next_pullup(dev, tm);
+ /* parasitic power delay after the convert */
+ if (!external_power) // if parasitic power
+ w1_next_pullup(dev, tms);
w1_write_8(dev, W1_CONVERT_TEMP);
- if (external_power) {
+ if (external_power) { // if normal power
mutex_unlock(&dev->mutex);
-
- sleep_rem = msleep_interruptible(tm);
+ sleep_rem = msleep_interruptible(tms);
if (sleep_rem != 0)
return -EINTR;
i = mutex_lock_interruptible(&dev->mutex);
if (i != 0)
return i;
- } else if (!w1_strong_pullup) {
- sleep_rem = msleep_interruptible(tm);
- if (sleep_rem != 0) {
- mutex_unlock(&dev->mutex);
- return -EINTR;
- }
}
- if (!w1_reset_select_slave(sl)) {
-
- w1_write_8(dev, W1_READ_SCRATCHPAD);
- if ((count = w1_read_block(dev, rom, 9)) != 9) {
- dev_warn(device, "w1_read_block() "
- "returned %u instead of 9.\n",
- count);
- }
-
- crc = w1_calc_crc8(rom, 8);
+ w1_reset_select_slave(sl);
+ w1_write_8(dev, W1_READ_SCRATCHPAD);
+ if ((count = w1_read_block(dev, rom, 9)) != 9) {
+ //dev_warn(device, "w1_read_block() returned %u instead of 9.\n", count);
+ }
- if (rom[8] == crc)
- verdict = 1;
+ crc = w1_calc_crc8(rom, 8);
+ if (rom[8] == crc) {
+ verdict = 1;
+ break;
}
}
-
- if (!w1_therm_check_rom(rom))
- break;
}
- for (i = 0; i < 9; ++i)
- c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", rom[i]);
- c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n",
- crc, (verdict) ? "YES" : "NO");
+ for (i = 0; i < 9; ++i) c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", rom[i]);
+ c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n", crc, (verdict) ? "YES" : "NO");
+
if (verdict)
memcpy(sl->rom, rom, sizeof(sl->rom));
else
- dev_warn(device, "18S20 doesn't respond to CONVERT_TEMP.\n");
+ dev_warn(device, "ds18x20 doesn't respond to CONVERT_TEMP.\n");
- for (i = 0; i < 9; ++i)
- c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", sl->rom[i]);
+ for (i = 0; i < 9; ++i) c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", sl->rom[i]);
+ c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n", w1_convert_temp(rom, sl->family->fid));
+ //c -= snprintf(buf + PAGE_SIZE - c, c, "Cycles=%d", 10-max_trying);
- c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n",
- w1_convert_temp(rom, sl->family->fid));
mutex_unlock(&dev->mutex);
return PAGE_SIZE - c;
set last param to "1"
------------------------------------------------------------
[leds_para]
red_led = port:PA15<1>default><default><1>
------------------------------------------------------------
convert to .bin
in boot.cmd (on top of the file) write:
------------------------------------------------------------
gpio set PA15
------------------------------------------------------------
recompile it with: mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr