diff -ur WebIOPi-0.7.1/htdocs/webiopi.js WebIOPi-Pi2/htdocs/webiopi.js --- WebIOPi-0.7.1/htdocs/webiopi.js 2014-02-24 01:37:07.000000000 +0900 +++ WebIOPi-Pi2/htdocs/webiopi.js 2015-06-26 15:53:13.812134121 +0900 @@ -73,7 +73,7 @@ this.readyCallback = null; this.context = "/"; this.GPIO = Array(54); - this.PINS = Array(27); + this.PINS = Array(41); this.TYPE = { DNC: {value: 0, style: "DNC", label: "--"}, @@ -577,7 +577,7 @@ RPiHeader.prototype.createTable = function (containerId) { var table = $(""); table.attr("id", "RPiHeader") - for (var pin=1; pin<=26; pin++) { + for (var pin=1; pin<=40; pin++) { var line = $(''); line.append(this.getFunctionCell(pin)) line.append(this.getDescriptionCell(pin, "right")) diff -ur WebIOPi-0.7.1/python/native/cpuinfo.c WebIOPi-Pi2/python/native/cpuinfo.c --- WebIOPi-0.7.1/python/native/cpuinfo.c 2012-10-29 06:26:10.000000000 +0900 +++ WebIOPi-Pi2/python/native/cpuinfo.c 2015-06-26 16:10:24.893330537 +0900 @@ -39,6 +39,12 @@ sscanf(buffer, "Hardware : %s", hardware); if (strcmp(hardware, "BCM2708") == 0) rpi_found = 1; + else if (strcmp(hardware, "BCM2709") == 0) + rpi_found = 1; + else if (strcmp(hardware, "BCM2835") == 0) + rpi_found = 1; + else if (strcmp(hardware, "BCM2711") == 0) + rpi_found = 1; sscanf(buffer, "Revision : %s", revision); } fclose(fp); @@ -60,6 +64,16 @@ (strcmp(revision, "0003") == 0) || (strcmp(revision, "1000003") == 0 )) return 1; - else // assume rev 2 (0004 0005 0006 1000004 1000005 1000006) + else if ((strcmp(revision, "0004") == 0) || + (strcmp(revision, "1000004") == 0 ) || + (strcmp(revision, "0005") == 0) || + (strcmp(revision, "1000005") == 0 ) || + (strcmp(revision, "0006") == 0) || + (strcmp(revision, "1000006") == 0 )) return 2; + else if ((strcmp(revision, "a01041") == 0) || + (strcmp(revision, "a21041") == 0 )) + return 3; + else // assume rev 4 + return 4; } diff -ur WebIOPi-0.7.1/python/native/gpio.c WebIOPi-Pi2/python/native/gpio.c --- WebIOPi-0.7.1/python/native/gpio.c 2013-02-04 07:04:18.000000000 +0900 +++ WebIOPi-Pi2/python/native/gpio.c 2015-06-26 18:25:43.873270911 +0900 @@ -20,6 +20,7 @@ SOFTWARE. */ +#include #include #include #include @@ -28,9 +29,8 @@ #include #include #include "gpio.h" +#include "cpuinfo.h" -#define BCM2708_PERI_BASE 0x20000000 -#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) #define FSEL_OFFSET 0 // 0x0000 #define SET_OFFSET 7 // 0x001c / 4 #define CLR_OFFSET 10 // 0x0028 / 4 @@ -43,6 +43,11 @@ #define PULLUPDN_OFFSET 37 // 0x0094 / 4 #define PULLUPDNCLK_OFFSET 38 // 0x0098 / 4 +#define PULLUPDN_OFFSET_2711_0 57 +#define PULLUPDN_OFFSET_2711_1 58 +#define PULLUPDN_OFFSET_2711_2 59 +#define PULLUPDN_OFFSET_2711_3 60 + #define PAGE_SIZE (4*1024) #define BLOCK_SIZE (4*1024) @@ -83,7 +88,31 @@ if ((uint32_t)gpio_mem % PAGE_SIZE) gpio_mem += PAGE_SIZE - ((uint32_t)gpio_mem % PAGE_SIZE); - gpio_map = (uint32_t *)mmap( (caddr_t)gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, GPIO_BASE); + char buffer[12]; + const char *ranges_file = "/proc/device-tree/soc/ranges"; + int info_fd = open(ranges_file, O_RDONLY); + + if (info_fd < 0) { + fprintf(stderr, "cannot open: %s", ranges_file); + return SETUP_MMAP_FAIL; + } + + ssize_t n = read(info_fd, buffer, sizeof(buffer)); + close(info_fd); + + if (n < 8) { + fprintf(stderr, "cannot read base address: %s", ranges_file); + return SETUP_MMAP_FAIL; + } + + uint32_t gpio_offset = 0x00200000; + uint32_t gpio_base = (buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7] << 0) + gpio_offset; + + if (gpio_base == gpio_offset) { + gpio_base = (buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + (buffer[11] << 0) + gpio_offset; + } + + gpio_map = (uint32_t *)mmap( (caddr_t)gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, gpio_base); if ((uint32_t)gpio_map < 0) return SETUP_MMAP_FAIL; @@ -93,21 +122,44 @@ void set_pullupdn(int gpio, int pud) { - int clk_offset = PULLUPDNCLK_OFFSET + (gpio/32); - int shift = (gpio%32); - - if (pud == PUD_DOWN) - *(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_DOWN; - else if (pud == PUD_UP) - *(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_UP; - else // pud == PUD_OFF - *(gpio_map+PULLUPDN_OFFSET) &= ~3; - - short_wait(); - *(gpio_map+clk_offset) = 1 << shift; - short_wait(); - *(gpio_map+PULLUPDN_OFFSET) &= ~3; - *(gpio_map+clk_offset) = 0; + // Check GPIO register + int is2711 = *(gpio_map+PULLUPDN_OFFSET_2711_3) != 0x6770696f; + if (is2711) { + // Pi 4 Pull-up/down method + int pullreg = PULLUPDN_OFFSET_2711_0 + (gpio >> 4); + int pullshift = (gpio & 0xf) << 1; + unsigned int pullbits; + unsigned int pull = 0; + if (pud == PUD_DOWN){ + pull = 2; + } else + if (pud == PUD_UP){ + pull = 1; + } + pullbits = *(gpio_map + pullreg); + pullbits &= ~(3 << pullshift); + pullbits |= (pull << pullshift); + *(gpio_map + pullreg) = pullbits; + } + else + { + // Legacy Pull-up/down method + int clk_offset = PULLUPDNCLK_OFFSET + (gpio/32); + int shift = (gpio%32); + + if (pud == PUD_DOWN) + *(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_DOWN; + else if (pud == PUD_UP) + *(gpio_map+PULLUPDN_OFFSET) = (*(gpio_map+PULLUPDN_OFFSET) & ~3) | PUD_UP; + else // pud == PUD_OFF + *(gpio_map+PULLUPDN_OFFSET) &= ~3; + + short_wait(); + *(gpio_map+clk_offset) = 1 << shift; + short_wait(); + *(gpio_map+PULLUPDN_OFFSET) &= ~3; + *(gpio_map+clk_offset) = 0; + } } //updated Eric PTAK - trouch.com diff -ur WebIOPi-0.7.1/python/webiopi/utils/version.py WebIOPi-Pi2/python/webiopi/utils/version.py --- WebIOPi-0.7.1/python/webiopi/utils/version.py 2015-02-05 05:21:44.000000000 +0900 +++ WebIOPi-Pi2/python/webiopi/utils/version.py 2015-06-26 15:53:20.262082357 +0900 @@ -6,9 +6,10 @@ PYTHON_MAJOR = sys.version_info.major BOARD_REVISION = 0 -_MAPPING = [[], [], []] +_MAPPING = [[], [], [], []] _MAPPING[1] = ["V33", "V50", 0, "V50", 1, "GND", 4, 14, "GND", 15, 17, 18, 21, "GND", 22, 23, "V33", 24, 10, "GND", 9, 25, 11, 8, "GND", 7] _MAPPING[2] = ["V33", "V50", 2, "V50", 3, "GND", 4, 14, "GND", 15, 17, 18, 27, "GND", 22, 23, "V33", 24, 10, "GND", 9, 25, 11, 8, "GND", 7] +_MAPPING[3] = ["V33", "V50", 2, "V50", 3, "GND", 4, 14, "GND", 15, 17, 18, 27, "GND", 22, 23, "V33", 24, 10, "GND", 9, 25, 11, 8, "GND", 7, "DNC", "DNC" , 5, "GND", 6, 12, 13, "GND", 19, 16, 26, 20, "GND", 21] try: @@ -21,8 +22,13 @@ if hex_cpurev.startswith("1000"): hex_cpurev = hex_cpurev[-4:] cpurev = int(hex_cpurev, 16) - BOARD_REVISION = 1 if (cpurev < 4) else 2 - + if cpurev < 4: + BOARD_REVISION = 1 + elif cpurev < 7: + BOARD_REVISION = 2 + else: + BOARD_REVISION = 3 + except: pass --- WebIOPi-0.7.1/python/webiopi/protocols/http.py 2014-02-22 07:31:18.000000000 +0900 +++ WebIOPi-Pi2/python/webiopi/protocols/http.py 2017-08-18 16:53:56.000000000 +0900 @@ -194,13 +194,23 @@ (contentType, encoding) = mime.guess_type(path) f = codecs.open(path, encoding=encoding) - data = f.read() + try: + data = f.read() + except UnicodeDecodeError: + f.close() + f = codecs.open(path, mode='rb', encoding=encoding) + data = f.read() f.close() self.send_response(200) self.send_header("Content-Type", contentType); - self.send_header("Content-Length", os.path.getsize(realPath)) - self.end_headers() - self.wfile.write(data) + try: + self.send_header("Content-Length", len(data.encode())) + self.end_headers() + self.wfile.write(data.encode()) + except AttributeError: + self.send_header("Content-Length", os.path.getsize(realPath)) + self.end_headers() + self.wfile.write(data) self.logRequest(200) def processRequest(self): --- WebIOPi-0.7.1/python/webiopi/utils/thread.py 2013-04-18 06:41:06.000000000 +0900 +++ WebIOPi-Pi2/python/webiopi/utils/thread.py 2019-06-25 00:48:56.953709736 +0900 @@ -33,14 +33,14 @@ task.stop() -def runLoop(func=None, async=False): +def runLoop(func=None, l_async=False): global RUNNING RUNNING = True signal.signal(signal.SIGINT, stop) signal.signal(signal.SIGTERM, stop) if func != None: - if async: + if l_async: TASKS.append(Task(func, True)) else: while RUNNING: