Jump to content

EvgeniK45

Members
  • Posts

    25
  • Joined

  • Last visited

Reputation Activity

  1. Like
    EvgeniK45 got a reaction from tkaiser in w1-therm driver modifications   
    Additionally, the already modified source files:  https://drive.google.com/open?id=0B-_e-jRDz7k0U1JUcWJFenRXSkk
     
    Hopefully, the archive file is available.
  2. Like
    EvgeniK45 got a reaction from tkaiser in w1-therm driver modifications   
    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;
  3. Like
    EvgeniK45 reacted to neomanic in DHCP after "no link" boot   
    I had the same issue today. It's not something I have to worry about since my application doesn't care about hotplug, but perhaps this will help you?
     
    http://askubuntu.com/questions/575487/network-eth0-dhcp-static-ip-and-autonegotiation-issues
  4. Like
    EvgeniK45 got a reaction from shahidali55 in U-boot control LED   
    in .fex file:
     
    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
     
    reboot device, now you have red led on boot...
     

×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines