From c5310ee5b545316d7b8770343908c19f1ff1cd0d Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Wed, 21 Dec 2016 13:48:44 +1100 Subject: drivers: Fix some minor spelling mistakes. respones -> response succeses -> successes --- drivers/nrf24l01/nrf24l01test.py | 4 ++-- drivers/sdcard/sdcard.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/nrf24l01/nrf24l01test.py b/drivers/nrf24l01/nrf24l01test.py index 264bc21c8..a25194d38 100644 --- a/drivers/nrf24l01/nrf24l01test.py +++ b/drivers/nrf24l01/nrf24l01test.py @@ -43,7 +43,7 @@ def master(): timeout = True if timeout: - print('failed, respones timed out') + print('failed, response timed out') num_failures += 1 else: @@ -57,7 +57,7 @@ def master(): # delay then loop pyb.delay(250) - print('master finished sending; succeses=%d, failures=%d' % (num_successes, num_failures)) + print('master finished sending; successes=%d, failures=%d' % (num_successes, num_failures)) def slave(): nrf = NRF24L01(SPI(2), Pin('Y5'), Pin('Y4'), payload_size=8) diff --git a/drivers/sdcard/sdcard.py b/drivers/sdcard/sdcard.py index 191630aeb..cbf447415 100644 --- a/drivers/sdcard/sdcard.py +++ b/drivers/sdcard/sdcard.py @@ -142,7 +142,7 @@ class SDCard: buf[5] = crc self.spi.write(buf) - # wait for the repsonse (response[7] == 0) + # wait for the response (response[7] == 0) for i in range(_CMD_TIMEOUT): response = self.spi.read(1, 0xff)[0] if not (response & 0x80): -- cgit v1.2.3 From 43d9f9916a7d13ae0bb32589b4bfee833678bbef Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 23 Jan 2017 14:36:19 +1100 Subject: drivers/display: Add driver and test for uPy LCD160CR display. --- drivers/display/lcd160cr.py | 464 +++++++++++++++++++++++++++++++++++++++ drivers/display/lcd160cr_test.py | 161 ++++++++++++++ 2 files changed, 625 insertions(+) create mode 100644 drivers/display/lcd160cr.py create mode 100644 drivers/display/lcd160cr_test.py (limited to 'drivers') diff --git a/drivers/display/lcd160cr.py b/drivers/display/lcd160cr.py new file mode 100644 index 000000000..0861f8233 --- /dev/null +++ b/drivers/display/lcd160cr.py @@ -0,0 +1,464 @@ +# Driver for official MicroPython LCD160CR display +# MIT license; Copyright (c) 2017 Damien P. George + +from micropython import const +from utime import sleep_ms +from ustruct import calcsize, pack_into +import uerrno, machine + +# for set_orient +PORTRAIT = const(0) +LANDSCAPE = const(1) +PORTRAIT_UPSIDEDOWN = const(2) +LANDSCAPE_UPSIDEDOWN = const(3) + +# for set_startup_deco; can be or'd +STARTUP_DECO_NONE = const(0) +STARTUP_DECO_MLOGO = const(1) +STARTUP_DECO_INFO = const(2) + +_uart_baud_table = { + 2400: 0, + 4800: 1, + 9600: 2, + 19200: 3, + 38400: 4, + 57600: 5, + 115200: 6, + 230400: 7, + 460800: 8, +} + +class LCD160CR: + def __init__(self, connect=None, *, pwr=None, i2c=None, spi=None, i2c_addr=98): + if connect in ('X', 'Y', 'XY', 'YX'): + i = connect[-1] + j = connect[0] + y = j + '4' + elif connect == 'C': + i = 2 + j = 2 + y = 'A7' + else: + if pwr is None or i2c is None or spi is None: + raise ValueError('must specify valid "connect" or all of "pwr", "i2c" and "spi"') + + if pwr is None: + pwr = machine.Pin(y, machine.Pin.OUT) + if i2c is None: + i2c = machine.I2C(i, freq=1000000) + if spi is None: + spi = machine.SPI(j, baudrate=13500000, polarity=0, phase=0) + + if not pwr.value(): + pwr(1) + sleep_ms(10) + # else: + # alread have power + # lets be optimistic... + + # set connections + self.pwr = pwr + self.i2c = i2c + self.spi = spi + self.i2c_addr = i2c_addr + + # create temp buffers and memoryviews + self.buf16 = bytearray(16) + self.buf19 = bytearray(19) + self.buf = [None] * 10 + for i in range(1, 10): + self.buf[i] = memoryview(self.buf16)[0:i] + self.buf1 = self.buf[1] + self.array4 = [0, 0, 0, 0] + + # set default orientation and window + self.set_orient(PORTRAIT) + self._fcmd2b('= n: + self.i2c.readfrom_into(self.i2c_addr, buf) + return + t -= 1 + sleep_ms(1) + raise OSError(uerrno.ETIMEDOUT) + + def oflush(self, n=255): + t = 5000 + while t: + self.i2c.readfrom_into(self.i2c_addr + 1, self.buf1) + r = self.buf1[0] + if r >= n: + return + t -= 1 + machine.idle() + raise OSError(uerrno.ETIMEDOUT) + + def iflush(self): + t = 5000 + while t: + self.i2c.readfrom_into(self.i2c_addr, self.buf16) + if self.buf16[0] == 0: + return + t -= 1 + sleep_ms(1) + raise OSError(uerrno.ETIMEDOUT) + + #### MISC METHODS #### + + @staticmethod + def rgb(r, g, b): + return ((b & 0xf8) << 8) | ((g & 0xfc) << 3) | (r >> 3) + + @staticmethod + def clip_line(c, w, h): + while True: + ca = ce = 0 + if c[1] < 0: + ca |= 8 + elif c[1] > h: + ca |= 4 + if c[0] < 0: + ca |= 1 + elif c[0] > w: + ca |= 2 + if c[3] < 0: + ce |= 8 + elif c[3] > h: + ce |= 4 + if c[2] < 0: + ce |= 1 + elif c[2] > w: + ce |= 2 + if ca & ce: + return False + elif ca | ce: + ca |= ce + if ca & 1: + if c[2] < c[0]: + c[0], c[2] = c[2], c[0] + c[1], c[3] = c[3], c[1] + c[1] += ((-c[0]) * (c[3] - c[1])) // (c[2] - c[0]) + c[0] = 0 + elif ca & 2: + if c[2] < c[0]: + c[0], c[2] = c[2], c[0] + c[1], c[3] = c[3], c[1] + c[3] += ((w - 1 - c[2]) * (c[3] - c[1])) // (c[2] - c[0]) + c[2] = w - 1 + elif ca & 4: + if c[0] == c[2]: + if c[1] >= h: + c[1] = h - 1 + if c[3] >= h: + c[3] = h - 1 + else: + if c[3] < c[1]: + c[0], c[2] = c[2], c[0] + c[1], c[3] = c[3], c[1] + c[2] += ((h - 1 - c[3]) * (c[2] - c[0])) // (c[3] - c[1]) + c[3] = h - 1 + else: + if c[0] == c[2]: + if c[1] < 0: + c[1] = 0 + if c[3] < 0: + c[3] = 0 + else: + if c[3] < c[1]: + c[0], c[2] = c[2], c[0] + c[1], c[3] = c[3], c[1] + c[0] += ((-c[1]) * (c[2] - c[0])) // (c[3] - c[1]) + c[1] = 0 + else: + return True + + #### SETUP COMMANDS #### + + def set_power(self, on): + self.pwr(value) + sleep_ms(15) + + def set_orient(self, orient): + self._fcmd2('= 2: + self.i2c.readfrom_into(self.i2c_addr, self.buf[3]) + return self.buf[3][1] + self.buf[3][2] << 8 + t -= 1 + sleep_ms(1) + raise OSError(uerrno.ETIMEDOUT) + + def get_line(self, x, y, buf): + l = len(buf) // 2 + self._fcmd2b('= l: + self.i2c.readfrom_into(self.i2c_addr, buf) + return + t -= 1 + sleep_ms(1) + raise OSError(uerrno.ETIMEDOUT) + + def screen_dump(self, buf): + line = bytearray(self.w + 1) + h = len(buf) // (2 * self.w) + if h > self.h: + h = self.h + for i in range(h): + ix = i * self.w * 2 + self.get_line(0, i, line) + for j in range(1, len(line)): + buf[ix] = line[j] + ix += 1 + self.get_line(self.w // 2, i, line) + for j in range(1, len(line)): + buf[ix] = line[j] + ix += 1 + + def screen_load(self, buf): + l = self.w * self.h * 2+2 + self._fcmd2b('= 0x200: + self._send(ar[n:n + 0x200]) + n += 0x200 + else: + self._send(ar[n:]) + while n < self.w * self.h * 2: + self._send(b'\x00') + n += 1 + + #### TEXT COMMANDS #### + + def set_pos(self, x, y): + self._fcmd2('= self.w or y >= self.h: + return + elif x < 0 or y < 0: + left = top = True + if x < 0: + left = False + w += x + x = 0 + if y < 0: + top = False + h += y + y = 0 + if cmd == 0x51 or cmd == 0x72: + # draw interior + self._fcmd2b('> 7 != 0 + + def get_touch(self): + self._send(b'\x02T') # implicit LCD output flush + b = self.buf[4] + self._waitfor(3, b) + return b[1] >> 7, b[2], b[3] + + #### ADVANCED COMMANDS #### + + def set_spi_win(self, x, y, w, h): + pack_into(' 32: + raise ValueError('length must be 32 or less') + self._fcmd2(' 0: + s = '%6.3fV' % data[i] + else: + s = '%5.1f°C' % data[i] + lcd.set_font(1, bold=0, scale=1) + lcd.write(s) + +def test_features(lcd): + # if we run on pyboard then use ADC and RTC features + try: + import pyb + adc = pyb.ADCAll(12, 0xf0000) + rtc = pyb.RTC() + except: + adc = None + rtc = None + + # set orientation and clear screen + lcd = get_lcd(lcd) + lcd.set_orient(lcd160cr.PORTRAIT) + lcd.set_pen(0, 0) + lcd.erase() + + # create M-logo + mlogo = framebuf.FrameBuffer(bytearray(17 * 17 * 2), 17, 17, framebuf.RGB565) + mlogo.fill(0) + mlogo.fill_rect(1, 1, 15, 15, 0xffffff) + mlogo.vline(4, 4, 12, 0) + mlogo.vline(8, 1, 12, 0) + mlogo.vline(12, 4, 12, 0) + mlogo.vline(14, 13, 2, 0) + + # create inline framebuf + offx = 14 + offy = 19 + w = 100 + h = 75 + fbuf = framebuf.FrameBuffer(bytearray(w * h * 2), w, h, framebuf.RGB565) + lcd.set_spi_win(offx, offy, w, h) + + # initialise loop parameters + tx = ty = 0 + t0 = time.ticks_us() + + for i in range(300): + # update position of cross-hair + t, tx2, ty2 = lcd.get_touch() + if t: + tx2 -= offx + ty2 -= offy + if tx2 >= 0 and ty2 >= 0 and tx2 < w and ty2 < h: + tx, ty = tx2, ty2 + else: + tx = (tx + 1) % w + ty = (ty + 1) % h + + # create and show the inline framebuf + fbuf.fill(lcd.rgb(128 + int(64 * math.cos(0.1 * i)), 128, 192)) + fbuf.line(w // 2, h // 2, + w // 2 + int(40 * math.cos(0.2 * i)), + h // 2 + int(40 * math.sin(0.2 * i)), + lcd.rgb(128, 255, 64)) + fbuf.hline(0, ty, w, lcd.rgb(64, 64, 64)) + fbuf.vline(tx, 0, h, lcd.rgb(64, 64, 64)) + fbuf.rect(tx - 3, ty - 3, 7, 7, lcd.rgb(64, 64, 64)) + for phase in (-0.2, 0, 0.2): + x = w // 2 - 8 + int(50 * math.cos(0.05 * i + phase)) + y = h // 2 - 8 + int(32 * math.sin(0.05 * i + phase)) + fbuf.blit(mlogo, x, y) + for j in range(-3, 3): + fbuf.text('MicroPython', + 5, h // 2 + 9 * j + int(20 * math.sin(0.1 * (i + j))), + lcd.rgb(128 + 10 * j, 0, 128 - 10 * j)) + lcd.show_framebuf(fbuf) + + # show results from the ADC + if adc: + show_adc(lcd, adc) + + # show the time + if rtc: + lcd.set_pos(2, 0) + lcd.set_font(1) + t = rtc.datetime() + lcd.write('%4d-%02d-%02d %2d:%02d:%02d.%01d' % (t[0], t[1], t[2], t[4], t[5], t[6], t[7] // 100000)) + + # compute the frame rate + t1 = time.ticks_us() + dt = time.ticks_diff(t1, t0) + t0 = t1 + + # show the frame rate + lcd.set_pos(2, 9) + lcd.write('%.2f fps' % (1000000 / dt)) + +def test_mandel(lcd): + # set orientation and clear screen + lcd = get_lcd(lcd) + lcd.set_orient(lcd160cr.PORTRAIT) + lcd.set_pen(0, 0xffff) + lcd.erase() + + # function to compute Mandelbrot pixels + def in_set(c): + z = 0 + for i in range(32): + z = z * z + c + if abs(z) > 100: + return i + return 0 + + # cache width and height of LCD + w = lcd.w + h = lcd.h + + # create the buffer for each line and set SPI parameters + line = bytearray(w * 2) + lcd.set_spi_win(0, 0, w, h) + spi = lcd.fast_spi() + + # draw the Mandelbrot set line-by-line + for v in range(h): + for u in range(w): + c = in_set((v / ((h - 1) / 3.2) - 2.3) + (u / ((w - 1) / 2.4) - 1.2) * 1j) + if c < 16: + rgb = c << 12 | c << 6 + else: + rgb = 0xf800 | c << 6 + line[2 * u] = rgb + line[2 * u + 1] = rgb >> 8 + spi.write(line) + +def test_all(lcd): + lcd = get_lcd(lcd) + test_features(lcd) + test_mandel(lcd) + +print('To run all tests: test_all()') +print('Individual tests are: test_features, test_mandel') +print(' argument should be a connection, eg "X", or an LCD160CR object') -- cgit v1.2.3 From 784e023a2678a528708a2c1430d88e99d60d7128 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 24 Jan 2017 16:56:03 +1100 Subject: drivers/memory: Add SPI flash driver, written in C. --- drivers/memory/spiflash.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/memory/spiflash.h | 42 ++++++++++ 2 files changed, 242 insertions(+) create mode 100644 drivers/memory/spiflash.c create mode 100644 drivers/memory/spiflash.h (limited to 'drivers') diff --git a/drivers/memory/spiflash.c b/drivers/memory/spiflash.c new file mode 100644 index 000000000..214610e0a --- /dev/null +++ b/drivers/memory/spiflash.c @@ -0,0 +1,200 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016-2017 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "py/mperrno.h" +#include "py/mphal.h" +#include "extmod/machine_spi.h" +#include "drivers/memory/spiflash.h" + +#define CMD_WRITE (0x02) +#define CMD_READ (0x03) +#define CMD_WRDI (0x04) +#define CMD_RDSR (0x05) +#define CMD_WREN (0x06) +#define CMD_SEC_ERASE (0x20) +#define WAIT_SR_TIMEOUT (1000000) + +#define PAGE_SIZE (256) // maximum bytes we can write in one SPI transfer +#define SECTOR_SIZE (4096) // size of erase sector + +// Note: this code is not reentrant with this shared buffer +STATIC uint8_t buf[SECTOR_SIZE]; + +void mp_spiflash_init(mp_spiflash_t *self) { + mp_hal_pin_write(self->cs, 1); + mp_hal_pin_output(self->cs); + mp_hal_pin_write(self->spi.sck, 0); + mp_hal_pin_output(self->spi.sck); + mp_hal_pin_output(self->spi.mosi); + mp_hal_pin_input(self->spi.miso); +} + +STATIC void mp_spiflash_acquire_bus(mp_spiflash_t *self) { + // can be used for actions needed to acquire bus + (void)self; +} + +STATIC void mp_spiflash_release_bus(mp_spiflash_t *self) { + // can be used for actions needed to release bus + (void)self; +} + +STATIC void mp_spiflash_transfer(mp_spiflash_t *self, size_t len, const uint8_t *src, uint8_t *dest) { + mp_machine_soft_spi_transfer(&self->spi.base, len, src, dest); +} + +STATIC int mp_spiflash_wait_sr(mp_spiflash_t *self, uint8_t mask, uint8_t val, uint32_t timeout) { + uint8_t cmd[1] = {CMD_RDSR}; + mp_hal_pin_write(self->cs, 0); + mp_spiflash_transfer(self, 1, cmd, NULL); + for (; timeout; --timeout) { + mp_spiflash_transfer(self, 1, cmd, cmd); + if ((cmd[0] & mask) == val) { + break; + } + } + mp_hal_pin_write(self->cs, 1); + if ((cmd[0] & mask) == val) { + return 0; // success + } else if (timeout == 0) { + return -MP_ETIMEDOUT; + } else { + return -MP_EIO; + } +} + +STATIC int mp_spiflash_wait_wel1(mp_spiflash_t *self) { + return mp_spiflash_wait_sr(self, 2, 2, WAIT_SR_TIMEOUT); +} + +STATIC int mp_spiflash_wait_wip0(mp_spiflash_t *self) { + return mp_spiflash_wait_sr(self, 1, 0, WAIT_SR_TIMEOUT); +} + +STATIC void mp_spiflash_write_cmd(mp_spiflash_t *self, uint8_t cmd) { + mp_hal_pin_write(self->cs, 0); + mp_spiflash_transfer(self, 1, &cmd, NULL); + mp_hal_pin_write(self->cs, 1); +} + +STATIC int mp_spiflash_erase_sector(mp_spiflash_t *self, uint32_t addr) { + // enable writes + mp_spiflash_write_cmd(self, CMD_WREN); + + // wait WEL=1 + int ret = mp_spiflash_wait_wel1(self); + if (ret != 0) { + return ret; + } + + // erase the sector + mp_hal_pin_write(self->cs, 0); + uint8_t cmd[4] = {CMD_SEC_ERASE, addr >> 16, addr >> 8, addr}; + mp_spiflash_transfer(self, 4, cmd, NULL); + mp_hal_pin_write(self->cs, 1); + + // wait WIP=0 + return mp_spiflash_wait_wip0(self); +} + +STATIC int mp_spiflash_write_page(mp_spiflash_t *self, uint32_t addr, const uint8_t *src) { + // enable writes + mp_spiflash_write_cmd(self, CMD_WREN); + + // wait WEL=1 + int ret = mp_spiflash_wait_wel1(self); + if (ret != 0) { + return ret; + } + + // write the page + mp_hal_pin_write(self->cs, 0); + uint8_t cmd[4] = {CMD_WRITE, addr >> 16, addr >> 8, addr}; + mp_spiflash_transfer(self, 4, cmd, NULL); + mp_spiflash_transfer(self, PAGE_SIZE, src, NULL); + mp_hal_pin_write(self->cs, 1); + + // wait WIP=0 + return mp_spiflash_wait_wip0(self); +} + +void mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) { + mp_spiflash_acquire_bus(self); + uint8_t cmd[4] = {CMD_READ, addr >> 16, addr >> 8, addr}; + mp_hal_pin_write(self->cs, 0); + mp_spiflash_transfer(self, 4, cmd, NULL); + mp_spiflash_transfer(self, len, dest, dest); + mp_hal_pin_write(self->cs, 1); + mp_spiflash_release_bus(self); +} + +int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) { + // TODO optimise so we don't need to erase multiple times for successive writes to a sector + + // align to 4096 sector + uint32_t offset = addr & 0xfff; + addr = (addr >> 12) << 12; + + // restriction for now, so we don't need to erase multiple pages + if (offset + len > sizeof(buf)) { + printf("mp_spiflash_write: len is too large\n"); + return -MP_EIO; + } + + mp_spiflash_acquire_bus(self); + + // read sector + uint8_t cmd[4] = {CMD_READ, addr >> 16, addr >> 8, addr}; + mp_hal_pin_write(self->cs, 0); + mp_spiflash_transfer(self, 4, cmd, NULL); + mp_spiflash_transfer(self, SECTOR_SIZE, buf, buf); + mp_hal_pin_write(self->cs, 1); + + // erase sector + int ret = mp_spiflash_erase_sector(self, addr); + if (ret != 0) { + mp_spiflash_release_bus(self); + return ret; + } + + // copy new block into buffer + memcpy(buf + offset, src, len); + + // write sector in pages of 256 bytes + for (int i = 0; i < SECTOR_SIZE; i += 256) { + ret = mp_spiflash_write_page(self, addr + i, buf + i); + if (ret != 0) { + mp_spiflash_release_bus(self); + return ret; + } + } + + mp_spiflash_release_bus(self); + return 0; // success +} diff --git a/drivers/memory/spiflash.h b/drivers/memory/spiflash.h new file mode 100644 index 000000000..d2e817450 --- /dev/null +++ b/drivers/memory/spiflash.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_DRIVERS_MEMORY_SPIFLASH_H +#define MICROPY_INCLUDED_DRIVERS_MEMORY_SPIFLASH_H + +#include "extmod/machine_spi.h" + +typedef struct _mp_spiflash_t { + mp_hal_pin_obj_t cs; + // TODO replace with generic SPI object + mp_machine_soft_spi_obj_t spi; +} mp_spiflash_t; + +void mp_spiflash_init(mp_spiflash_t *self); +void mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest); +int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src); + +#endif // MICROPY_INCLUDED_DRIVERS_MEMORY_SPIFLASH_H -- cgit v1.2.3 From d5e9ab6e61729f533dbed5c2b6b27307ce6c3b55 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 5 Feb 2017 14:20:17 +0300 Subject: extmod/machine_pulse: Make time_pulse_us() not throw exceptions. machine.time_pulse_us() is intended to provide very fine timing, including while working with signal bursts, where each transition is tracked in row. Throwing and handling an exception may take too much time and "signal loss". So instead, in case of a timeout, just return negative value. Cases of timeout while waiting for initial signal stabilization, and during actual timing, are recognized. The documentation is updated accordingly, and rewritten somewhat to clarify the function behavior. --- docs/library/machine.rst | 11 +++++++---- drivers/dht/dht.c | 4 ++-- extmod/machine_pulse.c | 6 ++---- tests/extmod/machine_pulse.py | 11 ++--------- tests/extmod/machine_pulse.py.exp | 4 ++-- 5 files changed, 15 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/docs/library/machine.rst b/docs/library/machine.rst index 753f6b417..c6da71585 100644 --- a/docs/library/machine.rst +++ b/docs/library/machine.rst @@ -118,12 +118,15 @@ Miscellaneous functions microseconds. The `pulse_level` argument should be 0 to time a low pulse or 1 to time a high pulse. - The function first waits while the pin input is different to the `pulse_level` - parameter, then times the duration that the pin is equal to `pulse_level`. + If the current input value of the pin is different to `pulse_level`, + the function first (*) waits until the pin input becomes equal to `pulse_level`, + then (**) times the duration that the pin is equal to `pulse_level`. If the pin is already equal to `pulse_level` then timing starts straight away. - The function will raise an OSError with ETIMEDOUT if either of the waits is - longer than the given timeout value (which is in microseconds). + The function will return -2 if there was timeout waiting for condition marked + (*) above, and -1 if there was timeout during the main measurement, marked (**) + above. The timeout is the same for both cases and given by `timeout_us` (which + is in microseconds). .. _machine_constants: diff --git a/drivers/dht/dht.c b/drivers/dht/dht.c index 1f0cffc6f..6bdda44b4 100644 --- a/drivers/dht/dht.c +++ b/drivers/dht/dht.c @@ -65,7 +65,7 @@ STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) { // time pulse, should be 80us ticks = machine_time_pulse_us(pin, 1, 150); - if (ticks == (mp_uint_t)-1) { + if ((mp_int_t)ticks < 0) { goto timeout; } @@ -73,7 +73,7 @@ STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) { uint8_t *buf = bufinfo.buf; for (int i = 0; i < 40; ++i) { ticks = machine_time_pulse_us(pin, 1, 100); - if (ticks == (mp_uint_t)-1) { + if ((mp_int_t)ticks < 0) { goto timeout; } buf[i / 8] = (buf[i / 8] << 1) | (ticks > 48); diff --git a/extmod/machine_pulse.c b/extmod/machine_pulse.c index b2a78d72e..5f837479d 100644 --- a/extmod/machine_pulse.c +++ b/extmod/machine_pulse.c @@ -34,7 +34,7 @@ mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t mp_uint_t start = mp_hal_ticks_us(); while (mp_hal_pin_read(pin) != pulse_level) { if ((mp_uint_t)(mp_hal_ticks_us() - start) >= timeout_us) { - return (mp_uint_t)-1; + return (mp_uint_t)-2; } } start = mp_hal_ticks_us(); @@ -57,9 +57,7 @@ STATIC mp_obj_t machine_time_pulse_us_(size_t n_args, const mp_obj_t *args) { timeout_us = mp_obj_get_int(args[2]); } mp_uint_t us = machine_time_pulse_us(pin, level, timeout_us); - if (us == (mp_uint_t)-1) { - mp_raise_OSError(MP_ETIMEDOUT); - } + // May return -1 or -2 in case of timeout return mp_obj_new_int(us); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_time_pulse_us_obj, 2, 3, machine_time_pulse_us_); diff --git a/tests/extmod/machine_pulse.py b/tests/extmod/machine_pulse.py index b6e126435..6491b5409 100644 --- a/tests/extmod/machine_pulse.py +++ b/tests/extmod/machine_pulse.py @@ -43,12 +43,5 @@ t = machine.time_pulse_us(p, 0) print(type(t)) p = ConstPin(0) -try: - machine.time_pulse_us(p, 1, 10) -except OSError: - print("OSError") - -try: - machine.time_pulse_us(p, 0, 10) -except OSError: - print("OSError") +print(machine.time_pulse_us(p, 1, 10)) +print(machine.time_pulse_us(p, 0, 10)) diff --git a/tests/extmod/machine_pulse.py.exp b/tests/extmod/machine_pulse.py.exp index f9a474218..20d4c1043 100644 --- a/tests/extmod/machine_pulse.py.exp +++ b/tests/extmod/machine_pulse.py.exp @@ -5,5 +5,5 @@ value: 1 value: 0 value: 1 -OSError -OSError +-2 +-1 -- cgit v1.2.3 From 8f3e07f17d545d78fa031c1eba8e907a7cd08808 Mon Sep 17 00:00:00 2001 From: Stephan Brauer Date: Thu, 16 Feb 2017 21:49:25 +0100 Subject: drivers/display/lcd160cr: Use correct variable in set_power(). --- drivers/display/lcd160cr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/display/lcd160cr.py b/drivers/display/lcd160cr.py index 0861f8233..a5da64348 100644 --- a/drivers/display/lcd160cr.py +++ b/drivers/display/lcd160cr.py @@ -203,7 +203,7 @@ class LCD160CR: #### SETUP COMMANDS #### def set_power(self, on): - self.pwr(value) + self.pwr(on) sleep_ms(15) def set_orient(self, orient): -- cgit v1.2.3 From b0a6dda115e34436cc1774661a57348aee9dbb81 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 21 Feb 2017 17:40:34 +1100 Subject: drivers/display/lcd160cr: Fix bugs with lcd.get_pixel(). Fixes issues #2880 and #2881. --- drivers/display/lcd160cr.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/display/lcd160cr.py b/drivers/display/lcd160cr.py index a5da64348..c17a1f189 100644 --- a/drivers/display/lcd160cr.py +++ b/drivers/display/lcd160cr.py @@ -243,13 +243,13 @@ class LCD160CR: self._fcmd2b('= 2: self.i2c.readfrom_into(self.i2c_addr, self.buf[3]) - return self.buf[3][1] + self.buf[3][2] << 8 + return self.buf[3][1] | self.buf[3][2] << 8 t -= 1 sleep_ms(1) raise OSError(uerrno.ETIMEDOUT) -- cgit v1.2.3 From 8400d0461d3bb444f10242c82c5c44d4d7cbef16 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 24 Feb 2017 17:22:57 +1100 Subject: drivers/display/lcd160cr: Fix bug with save_to_flash method. --- drivers/display/lcd160cr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/display/lcd160cr.py b/drivers/display/lcd160cr.py index c17a1f189..d63dc3975 100644 --- a/drivers/display/lcd160cr.py +++ b/drivers/display/lcd160cr.py @@ -235,7 +235,7 @@ class LCD160CR: self._fcmd2(' Date: Mon, 27 Feb 2017 18:39:35 +1100 Subject: drivers/display/lcd160cr: Add check that JPEG size is less than 65536. --- drivers/display/lcd160cr.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/display/lcd160cr.py b/drivers/display/lcd160cr.py index d63dc3975..0cf52f2ef 100644 --- a/drivers/display/lcd160cr.py +++ b/drivers/display/lcd160cr.py @@ -446,6 +446,8 @@ class LCD160CR: self._send(s) def jpeg_start(self, l): + if l > 0xffff: + raise ValueError('length must be 65535 or less') self.oflush() self._fcmd2(' Date: Fri, 7 Apr 2017 15:54:21 +1000 Subject: drivers/nrf24l01: Update to work on newer ports, using machine, utime. Changes made are: - Use the time module in place of the pyb module for delays. - Use spi.read/spi.write instead of spi.send/spi.receive. - Drop some non-portable parameters to spi and pin initialization. Thanks to @deshipu for the original patch. --- drivers/nrf24l01/nrf24l01.py | 76 +++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/nrf24l01/nrf24l01.py b/drivers/nrf24l01/nrf24l01.py index 3c79650bf..788906dc0 100644 --- a/drivers/nrf24l01/nrf24l01.py +++ b/drivers/nrf24l01/nrf24l01.py @@ -2,7 +2,7 @@ """ from micropython import const -import pyb +import utime # nRF24L01+ registers CONFIG = const(0x00) @@ -53,22 +53,24 @@ class NRF24L01: def __init__(self, spi, cs, ce, channel=46, payload_size=16): assert payload_size <= 32 - # init the SPI bus and pins - spi.init(spi.MASTER, baudrate=4000000, polarity=0, phase=0, firstbit=spi.MSB) - cs.init(cs.OUT_PP, cs.PULL_NONE) - ce.init(ce.OUT_PP, ce.PULL_NONE) + self.buf = bytearray(1) # store the pins self.spi = spi self.cs = cs self.ce = ce + # init the SPI bus and pins + self.init_spi(4000000) + cs.init(cs.OUT, value=1) + ce.init(ce.OUT, value=0) + # reset everything self.ce.low() self.cs.high() self.payload_size = payload_size self.pipe0_read_addr = None - pyb.delay(5) + utime.sleep_ms(5) # set address width to 5 bytes and check for device present self.reg_write(SETUP_AW, 0b11) @@ -98,28 +100,44 @@ class NRF24L01: self.flush_rx() self.flush_tx() + def init_spi(self, baudrate): + try: + master = self.spi.MASTER + except AttributeError: + self.spi.init(baudrate=baudrate, polarity=0, phase=0) + else: + self.spi.init(master, baudrate=baudrate, polarity=0, phase=0) + def reg_read(self, reg): self.cs.low() - self.spi.send_recv(reg) - buf = self.spi.recv(1) + self.spi.readinto(self.buf, reg) + self.spi.readinto(self.buf) + self.cs.high() + return self.buf[0] + + def reg_write_bytes(self, reg, buf): + self.cs.low() + self.spi.readinto(self.buf, 0x20 | reg) + self.spi.write(buf) self.cs.high() - return buf[0] + return self.buf[0] - def reg_write(self, reg, buf): + def reg_write(self, reg, value): self.cs.low() - status = self.spi.send_recv(0x20 | reg)[0] - self.spi.send(buf) + self.spi.readinto(self.buf, 0x20 | reg) + ret = self.buf[0] + self.spi.readinto(self.buf, value) self.cs.high() - return status + return ret def flush_rx(self): self.cs.low() - self.spi.send(FLUSH_RX) + self.spi.readinto(self.buf, FLUSH_RX) self.cs.high() def flush_tx(self): self.cs.low() - self.spi.send(FLUSH_TX) + self.spi.readinto(self.buf, FLUSH_TX) self.cs.high() # power is one of POWER_x defines; speed is one of SPEED_x defines @@ -144,8 +162,8 @@ class NRF24L01: # address should be a bytes object 5 bytes long def open_tx_pipe(self, address): assert len(address) == 5 - self.reg_write(RX_ADDR_P0, address) - self.reg_write(TX_ADDR, address) + self.reg_write_bytes(RX_ADDR_P0, address) + self.reg_write_bytes(TX_ADDR, address) self.reg_write(RX_PW_P0, self.payload_size) # address should be a bytes object 5 bytes long @@ -157,7 +175,7 @@ class NRF24L01: if pipe_id == 0: self.pipe0_read_addr = address if pipe_id < 2: - self.reg_write(RX_ADDR_P0 + pipe_id, address) + self.reg_write_bytes(RX_ADDR_P0 + pipe_id, address) else: self.reg_write(RX_ADDR_P0 + pipe_id, address[0]) self.reg_write(RX_PW_P0 + pipe_id, self.payload_size) @@ -168,12 +186,12 @@ class NRF24L01: self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT) if self.pipe0_read_addr is not None: - self.reg_write(RX_ADDR_P0, self.pipe0_read_addr) + self.reg_write_bytes(RX_ADDR_P0, self.pipe0_read_addr) self.flush_rx() self.flush_tx() self.ce.high() - pyb.udelay(130) + utime.sleep_us(130) def stop_listening(self): self.ce.low() @@ -187,8 +205,8 @@ class NRF24L01: def recv(self): # get the data self.cs.low() - self.spi.send(R_RX_PAYLOAD) - buf = self.spi.recv(self.payload_size) + self.spi.readinto(self.buf, R_RX_PAYLOAD) + buf = self.spi.read(self.payload_size) self.cs.high() # clear RX ready flag self.reg_write(STATUS, RX_DR) @@ -198,9 +216,9 @@ class NRF24L01: # blocking wait for tx complete def send(self, buf, timeout=500): send_nonblock = self.send_start(buf) - start = pyb.millis() + start = utime.ticks_ms() result = None - while result is None and pyb.elapsed_millis(start) < timeout: + while result is None and utime.ticks_diff(utime.ticks_ms(), start) < timeout: result = self.send_done() # 1 == success, 2 == fail if result == 2: raise OSError("send failed") @@ -209,18 +227,18 @@ class NRF24L01: def send_start(self, buf): # power up self.reg_write(CONFIG, (self.reg_read(CONFIG) | PWR_UP) & ~PRIM_RX) - pyb.udelay(150) + utime.sleep_us(150) # send the data self.cs.low() - self.spi.send(W_TX_PAYLOAD) - self.spi.send(buf) + self.spi.readinto(self.buf, W_TX_PAYLOAD) + self.spi.write(buf) if len(buf) < self.payload_size: - self.spi.send(b'\x00' * (self.payload_size - len(buf))) # pad out data + self.spi.write(b'\x00' * (self.payload_size - len(buf))) # pad out data self.cs.high() # enable the chip so it can send the data self.ce.high() - pyb.udelay(15) # needs to be >10us + utime.sleep_us(15) # needs to be >10us self.ce.low() # returns None if send still in progress, 1 for success, 2 for fail -- cgit v1.2.3 From f351c6db5e4c0bf75d5d647e69a047da739606a8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 17 May 2017 19:53:13 +1000 Subject: drivers/display/lcd160cr: Fix get_line method and enhance screen_dump. The docs are updated and describe the new behaviour of these methods. --- docs/library/lcd160cr.rst | 18 +++++++++++++----- drivers/display/lcd160cr.py | 38 +++++++++++++++++++++++--------------- 2 files changed, 36 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/docs/library/lcd160cr.rst b/docs/library/lcd160cr.rst index 76828d32d..bd4741298 100644 --- a/docs/library/lcd160cr.rst +++ b/docs/library/lcd160cr.rst @@ -150,11 +150,19 @@ The following methods manipulate individual pixels on the display. .. method:: LCD160CR.get_line(x, y, buf) - Get a line of pixels into the given buffer. - -.. method:: LCD160CR.screen_dump(buf) - - Dump the entire screen to the given buffer. + Low-level method to get a line of pixels into the given buffer. + To read `n` pixels `buf` should be `2*n+1` bytes in length. The first byte + is a dummy byte and should be ignored, and subsequent bytes represent the + pixels in the line starting at coordinate `(x, y)`. + +.. method:: LCD160CR.screen_dump(buf, x=0, y=0, w=None, h=None) + + Dump the contents of the screen to the given buffer. The parameters `x` and `y` + specify the starting coordinate, and `w` and `h` the size of the region. If `w` + or `h` are `None` then they will take on their maximum values, set by the size + of the screen minus the given `x` and `y` values. `buf` should be large enough + to hold `2*w*h` bytes. If it's smaller then only the initial horizontal lines + will be stored. .. method:: LCD160CR.screen_load(buf) diff --git a/drivers/display/lcd160cr.py b/drivers/display/lcd160cr.py index 0cf52f2ef..dd9ab9985 100644 --- a/drivers/display/lcd160cr.py +++ b/drivers/display/lcd160cr.py @@ -257,6 +257,7 @@ class LCD160CR: def get_line(self, x, y, buf): l = len(buf) // 2 self._fcmd2b(' self.h: - h = self.h - for i in range(h): - ix = i * self.w * 2 - self.get_line(0, i, line) - for j in range(1, len(line)): - buf[ix] = line[j] - ix += 1 - self.get_line(self.w // 2, i, line) - for j in range(1, len(line)): - buf[ix] = line[j] - ix += 1 + def screen_dump(self, buf, x=0, y=0, w=None, h=None): + if w is None: + w = self.w - x + if h is None: + h = self.h - y + if w <= 127: + line = bytearray(2 * w + 1) + line2 = None + else: + # split line if more than 254 bytes needed + buflen = (w + 1) // 2 + line = bytearray(2 * buflen + 1) + line2 = memoryview(line)[:2 * (w - buflen) + 1] + for i in range(min(len(buf) // (2 * w), h)): + ix = i * w * 2 + self.get_line(x, y + i, line) + buf[ix:ix + len(line) - 1] = memoryview(line)[1:] + ix += len(line) - 1 + if line2: + self.get_line(x + buflen, y + i, line2) + buf[ix:ix + len(line2) - 1] = memoryview(line2)[1:] + ix += len(line2) - 1 def screen_load(self, buf): l = self.w * self.h * 2+2 -- cgit v1.2.3 From 55dd83a7bac340cbc85a8abafb1ff4eb2a187ce6 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 17 May 2017 19:54:38 +1000 Subject: drivers/display/lcd160cr_test: Allow test to take orientation parameter. --- drivers/display/lcd160cr_test.py | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/display/lcd160cr_test.py b/drivers/display/lcd160cr_test.py index 5571a4c3a..8b7ef4555 100644 --- a/drivers/display/lcd160cr_test.py +++ b/drivers/display/lcd160cr_test.py @@ -16,17 +16,25 @@ def show_adc(lcd, adc): pass for i in range(3): lcd.set_text_color((825, 1625, 1600)[i], 0) - lcd.set_font(2) - lcd.set_pos(0, 100 + i * 16) + if lcd.h == 160: + lcd.set_font(2) + lcd.set_pos(0, 100 + i * 16) + else: + lcd.set_font(2, trans=1) + lcd.set_pos(0, lcd.h-60 + i * 16) lcd.write('%4s: ' % ('TEMP', 'VBAT', 'VREF')[i]) if i > 0: s = '%6.3fV' % data[i] else: s = '%5.1f°C' % data[i] - lcd.set_font(1, bold=0, scale=1) + if lcd.h == 160: + lcd.set_font(1, bold=0, scale=1) + else: + lcd.set_font(1, bold=0, scale=1, trans=1) + lcd.set_pos(45, lcd.h-60 + i * 16) lcd.write(s) -def test_features(lcd): +def test_features(lcd, orient=lcd160cr.PORTRAIT): # if we run on pyboard then use ADC and RTC features try: import pyb @@ -38,7 +46,7 @@ def test_features(lcd): # set orientation and clear screen lcd = get_lcd(lcd) - lcd.set_orient(lcd160cr.PORTRAIT) + lcd.set_orient(orient) lcd.set_pen(0, 0) lcd.erase() @@ -114,10 +122,10 @@ def test_features(lcd): lcd.set_pos(2, 9) lcd.write('%.2f fps' % (1000000 / dt)) -def test_mandel(lcd): +def test_mandel(lcd, orient=lcd160cr.PORTRAIT): # set orientation and clear screen lcd = get_lcd(lcd) - lcd.set_orient(lcd160cr.PORTRAIT) + lcd.set_orient(orient) lcd.set_pen(0, 0xffff) lcd.erase() @@ -140,9 +148,11 @@ def test_mandel(lcd): spi = lcd.fast_spi() # draw the Mandelbrot set line-by-line + hh = ((h - 1) / 3.2) + ww = ((w - 1) / 2.4) for v in range(h): for u in range(w): - c = in_set((v / ((h - 1) / 3.2) - 2.3) + (u / ((w - 1) / 2.4) - 1.2) * 1j) + c = in_set((v / hh - 2.3) + (u / ww - 1.2) * 1j) if c < 16: rgb = c << 12 | c << 6 else: @@ -151,10 +161,10 @@ def test_mandel(lcd): line[2 * u + 1] = rgb >> 8 spi.write(line) -def test_all(lcd): +def test_all(lcd, orient=lcd160cr.PORTRAIT): lcd = get_lcd(lcd) - test_features(lcd) - test_mandel(lcd) + test_features(lcd, orient) + test_mandel(lcd, orient) print('To run all tests: test_all()') print('Individual tests are: test_features, test_mandel') -- cgit v1.2.3 From 1c9ee497562ab49c00d190ff91b6689979f922f4 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 23 Apr 2017 11:35:34 +0300 Subject: drivers: Replace deprecated Pin.high()/low() methods with .__call__(1/0). --- drivers/display/ssd1306.py | 22 +++++++++++----------- drivers/nrf24l01/nrf24l01.py | 40 ++++++++++++++++++++-------------------- drivers/onewire/ds18x20.py | 6 +++--- drivers/sdcard/sdcard.py | 24 ++++++++++++------------ 4 files changed, 46 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/display/ssd1306.py b/drivers/display/ssd1306.py index a8c11a1d0..53bcb0d2d 100644 --- a/drivers/display/ssd1306.py +++ b/drivers/display/ssd1306.py @@ -139,23 +139,23 @@ class SSD1306_SPI(SSD1306): def write_cmd(self, cmd): self.spi.init(baudrate=self.rate, polarity=0, phase=0) - self.cs.high() - self.dc.low() - self.cs.low() + self.cs(1) + self.dc(0) + self.cs(0) self.spi.write(bytearray([cmd])) - self.cs.high() + self.cs(1) def write_data(self, buf): self.spi.init(baudrate=self.rate, polarity=0, phase=0) - self.cs.high() - self.dc.high() - self.cs.low() + self.cs(1) + self.dc(1) + self.cs(0) self.spi.write(buf) - self.cs.high() + self.cs(1) def poweron(self): - self.res.high() + self.res(1) time.sleep_ms(1) - self.res.low() + self.res(0) time.sleep_ms(10) - self.res.high() + self.res(1) diff --git a/drivers/nrf24l01/nrf24l01.py b/drivers/nrf24l01/nrf24l01.py index 788906dc0..b45c137c6 100644 --- a/drivers/nrf24l01/nrf24l01.py +++ b/drivers/nrf24l01/nrf24l01.py @@ -66,8 +66,8 @@ class NRF24L01: ce.init(ce.OUT, value=0) # reset everything - self.ce.low() - self.cs.high() + self.ce(0) + self.cs(1) self.payload_size = payload_size self.pipe0_read_addr = None utime.sleep_ms(5) @@ -109,36 +109,36 @@ class NRF24L01: self.spi.init(master, baudrate=baudrate, polarity=0, phase=0) def reg_read(self, reg): - self.cs.low() + self.cs(0) self.spi.readinto(self.buf, reg) self.spi.readinto(self.buf) - self.cs.high() + self.cs(1) return self.buf[0] def reg_write_bytes(self, reg, buf): - self.cs.low() + self.cs(0) self.spi.readinto(self.buf, 0x20 | reg) self.spi.write(buf) - self.cs.high() + self.cs(1) return self.buf[0] def reg_write(self, reg, value): - self.cs.low() + self.cs(0) self.spi.readinto(self.buf, 0x20 | reg) ret = self.buf[0] self.spi.readinto(self.buf, value) - self.cs.high() + self.cs(1) return ret def flush_rx(self): - self.cs.low() + self.cs(0) self.spi.readinto(self.buf, FLUSH_RX) - self.cs.high() + self.cs(1) def flush_tx(self): - self.cs.low() + self.cs(0) self.spi.readinto(self.buf, FLUSH_TX) - self.cs.high() + self.cs(1) # power is one of POWER_x defines; speed is one of SPEED_x defines def set_power_speed(self, power, speed): @@ -190,11 +190,11 @@ class NRF24L01: self.flush_rx() self.flush_tx() - self.ce.high() + self.ce(1) utime.sleep_us(130) def stop_listening(self): - self.ce.low() + self.ce(0) self.flush_tx() self.flush_rx() @@ -204,10 +204,10 @@ class NRF24L01: def recv(self): # get the data - self.cs.low() + self.cs(0) self.spi.readinto(self.buf, R_RX_PAYLOAD) buf = self.spi.read(self.payload_size) - self.cs.high() + self.cs(1) # clear RX ready flag self.reg_write(STATUS, RX_DR) @@ -229,17 +229,17 @@ class NRF24L01: self.reg_write(CONFIG, (self.reg_read(CONFIG) | PWR_UP) & ~PRIM_RX) utime.sleep_us(150) # send the data - self.cs.low() + self.cs(0) self.spi.readinto(self.buf, W_TX_PAYLOAD) self.spi.write(buf) if len(buf) < self.payload_size: self.spi.write(b'\x00' * (self.payload_size - len(buf))) # pad out data - self.cs.high() + self.cs(1) # enable the chip so it can send the data - self.ce.high() + self.ce(1) utime.sleep_us(15) # needs to be >10us - self.ce.low() + self.ce(0) # returns None if send still in progress, 1 for success, 2 for fail def send_done(self): diff --git a/drivers/onewire/ds18x20.py b/drivers/onewire/ds18x20.py index 342f4b28a..72adcbfd4 100644 --- a/drivers/onewire/ds18x20.py +++ b/drivers/onewire/ds18x20.py @@ -7,11 +7,11 @@ temperature sensors. It supports multiple devices on the same 1-wire bus. The following example assumes the ground of your DS18x20 is connected to Y11, vcc is connected to Y9 and the data pin is connected to Y10. ->>> from pyb import Pin +>>> from machine import Pin >>> gnd = Pin('Y11', Pin.OUT_PP) ->>> gnd.low() +>>> gnd.off() >>> vcc = Pin('Y9', Pin.OUT_PP) ->>> vcc.high() +>>> vcc.on() >>> from ds18x20 import DS18X20 >>> d = DS18X20(Pin('Y10')) diff --git a/drivers/sdcard/sdcard.py b/drivers/sdcard/sdcard.py index cbf447415..e749d5376 100644 --- a/drivers/sdcard/sdcard.py +++ b/drivers/sdcard/sdcard.py @@ -130,7 +130,7 @@ class SDCard: raise OSError("timeout waiting for v2 card") def cmd(self, cmd, arg, crc, final=0, release=True): - self.cs.low() + self.cs(0) # create and send the command buf = self.cmdbuf @@ -150,12 +150,12 @@ class SDCard: for j in range(final): self.spi.write(b'\xff') if release: - self.cs.high() + self.cs(1) self.spi.write(b'\xff') return response # timeout - self.cs.high() + self.cs(1) self.spi.write(b'\xff') return -1 @@ -164,15 +164,15 @@ class SDCard: self.spi.read(1, 0xff) # ignore stuff byte for _ in range(_CMD_TIMEOUT): if self.spi.read(1, 0xff)[0] == 0xff: - self.cs.high() + self.cs(1) self.spi.write(b'\xff') return 0 # OK - self.cs.high() + self.cs(1) self.spi.write(b'\xff') return 1 # timeout def readinto(self, buf): - self.cs.low() + self.cs(0) # read until start byte (0xff) while self.spi.read(1, 0xff)[0] != 0xfe: @@ -186,11 +186,11 @@ class SDCard: self.spi.write(b'\xff') self.spi.write(b'\xff') - self.cs.high() + self.cs(1) self.spi.write(b'\xff') def write(self, token, buf): - self.cs.low() + self.cs(0) # send: start of block, data, checksum self.spi.read(1, token) @@ -200,7 +200,7 @@ class SDCard: # check the response if (self.spi.read(1, 0xff)[0] & 0x1f) != 0x05: - self.cs.high() + self.cs(1) self.spi.write(b'\xff') return @@ -208,18 +208,18 @@ class SDCard: while self.spi.read(1, 0xff)[0] == 0: pass - self.cs.high() + self.cs(1) self.spi.write(b'\xff') def write_token(self, token): - self.cs.low() + self.cs(0) self.spi.read(1, token) self.spi.write(b'\xff') # wait for write to finish while self.spi.read(1, 0xff)[0] == 0x00: pass - self.cs.high() + self.cs(1) self.spi.write(b'\xff') def count(self): -- cgit v1.2.3