Skip to content
View in the app

A better way to browse. Learn more.

Armbian Community Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

EvgeniK45

Members
  • 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...
     

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.