Esempio n. 1
1
from pyb import SPI

spi = SPI(1)
print(spi)

spi = SPI(1, SPI.MASTER)
spi = SPI(1, SPI.MASTER, baudrate=500000)
spi = SPI(1, SPI.MASTER, 500000, polarity=1, phase=0, bits=8, firstbit=SPI.MSB, ti=False, crc=None)
print(spi)

spi.init(SPI.SLAVE, phase=1)
print(spi)

spi.init(SPI.MASTER)
spi.send(1, timeout=100)
print(spi.recv(1, timeout=100))
print(spi.send_recv(1, timeout=100))
Esempio n. 2
0
def run():
    print('demo spi')
    spi = SPI(3, SPI.MASTER, baudrate=600000, polarity=1, phase=0, crc=0x7)
    while 1:
        tx = ''.join(chr(random.randint(50, 85)) for _ in range(4))
        rx = bytearray(4)

        spi.send_recv(tx, rx)

        print('tx: ' + str(tx))
        print('rx: ' + str(rx))

        time.sleep(2)
Esempio n. 3
0
class LIS302DL:
    def __init__(self):
        self.cs_pin = Pin('PE3', Pin.OUT_PP, Pin.PULL_NONE)
        self.cs_pin.high()
        self.spi = SPI(1,
                       SPI.MASTER,
                       baudrate=328125,
                       polarity=0,
                       phase=1,
                       bits=8)

    def rd(self, addr, nbytes):
        if nbytes > 1:
            addr |= READWRITE_CMD | MULTIPLEBYTE_CMD
        else:
            addr |= READWRITE_CMD
        self.cs_pin.low()
        self.spi.send(addr)
        buf = self.spi.send_recv(bytearray(nbytes *
                                           [0]))  # read data, MSB first
        self.cs_pin.high()
        return buf

    def wr(self, addr, buf):
        if len(buf) > 1:
            addr |= MULTIPLEBYTE_CMD
        self.cs_pin.low()
        self.spi.send(addr)
        for b in buf:
            self.spi.send(b)
        self.cs_pin.high()

    def read_id(self):
        return self.rd(LIS302DL_WHO_AM_I_ADDR, 1)

    def init(self, init_param=0x47, filter_param=0x2D):
        self.wr(LIS302DL_CTRL_REG1_ADDR, bytearray([init_param]))
        self.wr(LIS302DL_CTRL_REG2_ADDR, bytearray([filter_param]))

    def getx(self):
        buf = (self.rd(0x29, 1)[0]) - 1
        if buf > 127:
            return ((256 - buf) * (-1)) / 5.81
        else:
            return buf / 5.81

    def gety(self):
        buf = (self.rd(0x2B, 1)[0]) - 4
        if buf > 127:
            return ((256 - buf) * (-1)) / 5.81
        else:
            return buf / 5.81

    def getz(self):
        buf = (self.rd(0x2D, 1)[0]) + 8
        if buf > 127:
            return ((256 - buf) * (-1)) / 5.81
        else:
            return buf / 5.81
Esempio n. 4
0
class L3GD20:
    def __init__(self):
        self.csPin = Pin('PE3', Pin.OUT_PP, Pin.PULL_NONE)
        self.csPin.high()
        self.spi = SPI(1, SPI.MASTER, baudrate=328125, polarity=0, phase=1, bits=8)
        
    def read(self, address, nbytes):
        if nbytes > 1:
            address |= READWRITE_CMD | MULTIPLEBYTE_CMD
        else:
            address |= READWRITE_CMD
        self.csPin.low()
        self.spi.send(address)
        buf = self.spi.send_recv(bytearray(nbytes * [0])) # read data, MSB first
        self.csPin.high()
        return buf

    def write(self, address, buf):
        if len(buf) > 1:
            address |= MULTIPLEBYTE_CMD
        self.csPin.low()
        self.spi.send(address)
        for b in buf:
            self.spi.send(b)
        self.csPin.high()

    def readID(self):
        return (self.read(L3GD20_WHO_AM_I_ADDR, 1)[0])
        
    def initGyro(self, reg1Param = 0x3F, reg2Param = 0x00, reg4Param = 0x10):
        self.write(L3GD20_CTRL_REG1_ADDR, bytearray([reg1Param]))
        self.write(L3GD20_CTRL_REG2_ADDR, bytearray([reg2Param]))
        self.write(L3GD20_CTRL_REG4_ADDR, bytearray([reg4Param]))

    def getXGyro(self):
        buf = (self.read(L3GD20_OUT_X_L_ADDR,2))
        num = buf[1] << 8 | buf[0]
        return (s16(num)*17.50*0.001)
        
    def getYGyro(self):
        buf = (self.read(L3GD20_OUT_Y_L_ADDR,2))
        num = buf[1] << 8 | buf[0]
        return (s16(num)*17.50*0.001)
        
    def getZGyro(self):
        buf = (self.read(L3GD20_OUT_Z_L_ADDR,2))
        num = buf[1] << 8 | buf[0]
        return (s16(num)*17.50*0.001)
        
    def getTempGyro(self):
        buf = (self.read(L3GD20_OUT_TEMP_ADDR,1)[0])
        return s16(buf)
Esempio n. 5
0
class STAccel:
    def __init__(self):
        self.cs_pin = Pin('PE3', Pin.OUT_PP, Pin.PULL_NONE)
        self.cs_pin.high()
        self.spi = SPI(1,
                       SPI.MASTER,
                       baudrate=328125,
                       polarity=0,
                       phase=1,
                       bits=8)
        self.wr(LIS302DL_CTRL_REG1_ADDR, bytearray([LIS302DL_CONF]))

    def rd(self, addr, nbytes):
        if nbytes > 1:
            addr |= READWRITE_CMD | MULTIPLEBYTE_CMD
        else:
            addr |= READWRITE_CMD
        self.cs_pin.low()
        self.spi.send(addr)
        buf = self.spi.send_recv(bytearray(nbytes *
                                           [0]))  # read data, MSB first
        self.cs_pin.high()
        return buf

    def wr(self, addr, buf):
        if len(buf) > 1:
            addr |= MULTIPLEBYTE_CMD
        self.cs_pin.low()
        self.spi.send(addr)
        for b in buf:
            self.spi.send(b)
        self.cs_pin.high()

    def read_id(self):
        return self.rd(LIS302DL_WHO_AM_I_ADDR, 1)

    def get_xyz(self):
        val = self.rd(LIS302DL_OUT_X, 5)
        x = signed8(val[0]) * 18.0 / 1000
        y = signed8(val[2]) * 18.0 / 1000
        z = signed8(val[4]) * 18.0 / 1000
        return [x, y, z]
Esempio n. 6
0
class STAccel:
    def __init__(self):
        self.cs_pin = Pin('PE3', Pin.OUT_PP, Pin.PULL_NONE)
        self.cs_pin.high()
        self.spi = SPI(1, SPI.MASTER, baudrate=328125, polarity=0, phase=1, bits=8)
        self.wr(LIS302DL_CTRL_REG1_ADDR, bytearray([LIS302DL_CONF]))

    def rd(self, addr, nbytes):
        if nbytes > 1:
            addr |= READWRITE_CMD | MULTIPLEBYTE_CMD
        else:
            addr |= READWRITE_CMD
        self.cs_pin.low()
        self.spi.send(addr)
        buf = self.spi.send_recv(bytearray(nbytes * [0])) # read data, MSB first
        self.cs_pin.high()
        return buf

    def wr(self, addr, buf):
        if len(buf) > 1:
            addr |= MULTIPLEBYTE_CMD
        self.cs_pin.low()
        self.spi.send(addr)
        for b in buf:
            self.spi.send(b)
        self.cs_pin.high()

    def read_id(self):
        return self.rd(LIS302DL_WHO_AM_I_ADDR, 1)

    def get_xyz(self):
        val = self.rd(LIS302DL_OUT_X, 5)
        x = signed8(val[0]) * 18.0 / 1000
        y = signed8(val[2]) * 18.0 / 1000
        z = signed8(val[4]) * 18.0 / 1000
        return [x, y, z]
Esempio n. 7
0
print(spi)

spi = SPI(1, SPI.CONTROLLER)
spi = SPI(1, SPI.CONTROLLER, baudrate=500000)
spi = SPI(1,
          SPI.CONTROLLER,
          500000,
          polarity=1,
          phase=0,
          bits=8,
          firstbit=SPI.MSB,
          ti=False,
          crc=None)
print(str(spi)[:32], str(spi)[53:])  # don't print baudrate/prescaler

spi.init(SPI.PERIPHERAL, phase=1)
print(spi)
try:
    # need to flush input before we get an error (error is what we want to test)
    for i in range(10):
        spi.recv(1, timeout=100)
except OSError:
    print("OSError")

spi.init(SPI.CONTROLLER)
spi.send(1, timeout=100)
print(spi.recv(1, timeout=100))
print(spi.send_recv(1, timeout=100))

spi.deinit()
Esempio n. 8
0
adc = ADC(Pin('X19'))
adc.read() # read value, 0-4095

from pyb import Pin, DAC

dac = DAC(Pin('X5'))
dac.write(120) # output between 0 and 255

# SPI
from pyb import SPI

spi = SPI(1, SPI.MASTER, baudrate=200000, polarity=1, phase=0)
spi.send('hello')
spi.recv(5) # receive 5 bytes on the bus
spi.send_recv('hello') # send a receive 5 bytes

# I2C
from pyb import I2C

i2c = I2C(1, I2C.MASTER, baudrate=100000)
i2c.scan() # returns list of slave addresses
i2c.send('hello', 0x42) # send 5 bytes to slave with address 0x42
i2c.recv(5, 0x42) # receive 5 bytes from slave
i2c.mem_read(2, 0x42, 0x10) # read 2 bytes from slave 0x42, slave memory 0x10
i2c.mem_write('xy', 0x42, 0x10) # write 2 bytes to slave 0x42, slave memory 0x10

'''
To enter safe mode, do the following steps:

    Connect the pyboard to USB so it powers up.
Esempio n. 9
0
class MCP23S08(object):

    ADDRESS = 0b0100000
    STRUCT = "BBB"
    REGISTERS = {
        "IODIR": (0x00, 0b11111111),
        "IPOL": (0x01, 0b00000000),
        "GPINTEN": (0x02, 0b00000000),
        "DEFVAL": (0x03, 0b00000000),
        "INTCON": (0x04, 0b00000000),
        "IOCON": (0x05, 0b00000000),
        "GPPU": (0x06, 0b00000000),
        "INTF": (0x07, 0b00000000),
        "INTCAP": (0x08, 0b00000000),
        "GPIO": (0x09, 0b00000000),
        "OLAT": (0x0A, 0b00000000)
    }

    def __init__(self, cs=Pin.cpu.A4):
        self.__cs = Pin(cs, Pin.OUT_PP)
        self.__cs.high()
        self.__spi = SPI(1, SPI.MASTER, baudrate=10000, polarity=1, phase=1)
        self.reset()

    def reset(self):
        for reg in MCP23S08.REGISTERS.values():
            self.write_register(reg, reg[1])

    def read_register(self, register):
        buf = bytearray(
            struct.pack(MCP23S08.STRUCT, (MCP23S08.ADDRESS << 1) | 1,
                        register[0], 0))
        self.__cs.low()
        self.__spi.send_recv(buf, buf)
        self.__cs.high()
        return buf[2]

    def write_register(self, register, value):
        buf = bytearray(
            struct.pack(MCP23S08.STRUCT, MCP23S08.ADDRESS << 1, register[0],
                        value))
        self.__cs.low()
        self.__spi.send_recv(buf, buf)
        self.__cs.high()

    def set_directions(self, directions):
        self.write_register(MCP23S08.REGISTERS["IODIR"], directions)

    def get_directions(self):
        return self.read_register(MCP23S08.REGISTERS["IODIR"])

    def set_direction(self, idx, direction):
        self.set_directions(
            TMC_helpers.field_set(self.get_directions(), (1 << idx), idx,
                                  direction))

    def get_direction(self, idx):
        return TMC_helpers.field_get(self.get_directions(), (1 << idx), idx)

    def set_pullups(self, pullups):
        self.write_register(MCP23S08.REGISTERS["GPPU"], pullups)

    def get_pullups(self):
        return self.read_register(MCP23S08.REGISTERS["GPPU"])

    def set_pullup(self, idx, pullup):
        self.set_pullups(
            TMC_helpers.field_set(self.get_pullups(), (1 << idx), idx, pullup))

    def get_pullup(self, idx):
        return TMC_helpers.field_get(self.get_pullups(), (1 << idx), idx)

    def set_gpios(self, gpios):
        self.write_register(MCP23S08.REGISTERS["GPIO"], gpios)

    def get_gpios(self):
        return self.read_register(MCP23S08.REGISTERS["GPIO"])

    def set_gpio(self, idx, gpio):
        self.set_gpios(
            TMC_helpers.field_set(self.get_gpios(), (1 << idx), idx, gpio))

    def get_gpio(self, idx):
        return TMC_helpers.field_get(self.get_gpios(), (1 << idx), idx)
pyb.Pin("P3", pyb.Pin.IN, pull=pyb.Pin.PULL_UP)

# loop ad infinitum
while True:

    # flash light off to indicate waiting for SPI signal
    pyb.LED(RED_LED_PIN).off()

    # prepare/refresh buffer
    buf = bytearray(5)

    # for troubleshooting
    # print(buf)

    # send/receive message
    # spi.recv(buf)  # for receiving only
    spi.send_recv(b'heyyy', buf)

    # for troubleshooting
    # print(buf)

    # print received message
    print(''.join(chr(b) for b in buf))

    # flash light on to indicate reception of SPI signal
    pyb.LED(RED_LED_PIN).on()

    # pause briefly to indicate end of loop
    sensor.skip_frames(1)

Esempio n. 11
0
    f.write(img_data)

print('Save Checkpoint 3!')
'''

# print img_data for troubleshooting (should see bytes, 'JFIF', and weird stuff like P7<F<2PFAFZUP_)
# print(img_data)

### Communication

# flash light to indicate waiting for SPI signal
pyb.LED(RED_LED_PIN).on()

# prepare hello_buffer
hello_buffer = bytearray(5)
spi.send_recv(b'ready', hello_buffer)

# print message received from MCU
print(''.join(chr(b) for b in hello_buffer))

# determine size of image
# image_size = img.size()  # if img is being sent to MCU
image_size = len(img_data)  # if img_data is being sent to MCU

# create new size_buffer based on image_size
size_buffer = bytearray(len(
    str(image_size)))  # str() converts num 2 str, len() produces numeric input

# send that size to the MCU in a robust way
# print(str(image_size))  # print for troubleshooting
spi.send_recv(bytearray(str(image_size)), size_buffer)
                               pixels_threshold=1,
                               area_threshold=1,
                               x_stride=1):
        #st mask.lighten(blob.x(), blob.y(), blob.w(), blob.h())
        if (enable_masking and mask.ispersist(blob.cx(), blob.cy())):
            img.draw_rectangle(blob.rect(), color=(0, 255, 0))
            continue
        else:
            img.draw_cross(blob.cx(), blob.cy())
        str = struct.pack('<HHHHHH', fcount, bcount, blob.cx(), blob.cy(),
                          blob.w(), blob.h())
        while hs.value() == 0:
            pyb.delay(1)
        cs.low()
        pyb.udelay(1)
        spi.send_recv(str, rbuf)
        pyb.udelay(1)
        cs.high()
        pyb.udelay(10)
        bcount = bcount + 1

    # end of frame packet
    while hs.value() == 0:
        pyb.delay(1)
    str = struct.pack('<HHHHHH', 0xa5a5, 0, 0, 0, 0, 0)
    cs.low()
    pyb.udelay(1)
    spi.send_recv(str, rbuf)
    pyb.udelay(1)
    cs.high()
    pyb.udelay(10)
Esempio n. 13
0
class RFM69:
	def __init__(self, reset_pin=None, dio0_pin=None, spi_channel=None, config=None):
		self.reset_pin = reset_pin
		self.nss = Pin('X5', Pin.OUT_PP)
		self.reset = self.reset()
		self.spi_channel = spi_channel
		self.spi = SPI(1, SPI.MASTER, baudrate=50000, polarity=0, phase=0, firstbit=SPI.MSB, crc=None)
		self.dio0_pin = 'X3'
		self.conf = self.configure()
		self.mode = self.set_mode()

		self.txBufLen = 0
		self.txBuf = bytearray(registers["RFM69_MAX_MESSAGE_LEN"])
		
		self.rxBufLen = 0
		self.rxBuf = bytearray(registers["RFM69_MAX_MESSAGE_LEN"])

		self.version = self.getVersion()
		self.lastRssi = -(self.spi_read(registers["RFM69_REG_24_RSSI_VALUE"])/2)
		self.paLevel = 15

	def configure(self):
		print ("Configuring...")
		for reg, value in config.items():
			self.spi_write(registers.get(reg), value)
		return True

	def getVersion(self):
		self.version = self.spi_read(registers["RFM69_REG_10_VERSION"])
		return self.version

	def set_mode(self, newMode=registers["RFM69_MODE_RX"]):
		self.spi_write(registers["RFM69_REG_01_OPMODE"], (self.spi_read(registers["RFM69_REG_01_OPMODE"]) & 0xE3) | newMode)
		while(self.spi_read(registers["RFM69_REG_01_OPMODE"]) != newMode):
			self.spi_write(registers["RFM69_REG_01_OPMODE"], (self.spi_read(registers["RFM69_REG_01_OPMODE"]) & 0xE3) | newMode)
			print ("Waiting... Attempted mode: %d" % newMode)
			sleep(1)
			pass
		self.mode = newMode
		return newMode

	def get_mode(self):
		#self.mode = self.spi_read(registers["RFM69_REG_01_OPMODE"])
		return self.mode

	def init_gpio(self):
		self.dio0_pin = Pin('X3', Pin.IN, Pin.PULL_DOWN)

	def init_spi(self):
		self.spi = SPI(1, SPI.MASTER, baudrate=50000, polarity=0, phase=0, firstbit=SPI.MSB, crc=None)

	def reset(self):
		""" Reset the module, then check it's working. """
		print ("Initialising RFM...")

		self.nss.high()

		self.reset_pin = Pin('X4', Pin.OUT_PP)
		self.reset_pin.low()                
		sleep(0.1)
		self.reset_pin.high()
		sleep(0.1) 
		self.reset_pin.low()                
		sleep(0.1)

	def checkRx(self):
		print ("MODE: %d" % self.get_mode())
		print ("Waiting for Payload")
		while ((self.spi_read(registers["RFM69_REG_28_IRQ_FLAGS2"]) & registers["RF_IRQFLAGS2_PAYLOADREADY"]) != registers["RF_IRQFLAGS2_PAYLOADREADY"]):
			pass
		print ("MODE: %d" % self.spi_read(registers["RFM69_REG_01_OPMODE"]))
		print ("IRQ Flag: %d" % self.spi_read(registers["RFM69_REG_28_IRQ_FLAGS2"]))
		self.rxBufLen = self.spi_read(registers["RFM69_REG_00_FIFO"])+1
		print ("RX Buffer Length: %d" % self.rxBufLen)
		self.rxBuf = self.spi_burst_read(registers["RFM69_REG_00_FIFO"], registers["RFM69_FIFO_SIZE"])
		self.lastRssi = -(self.spi_read(registers["RFM69_REG_24_RSSI_VALUE"])/2)
		self.clearFifo()

	def recv(self):
		# Store received data for return
		rxTuple = (self.rxBuf, self.rxBufLen, self.lastRssi)

		# Clear RX buffer
		self.rxBufLen = 0
		self.rxBuf = bytearray(registers["RFM69_MAX_MESSAGE_LEN"])
		
		# Return received telemetry
		return rxTuple

	def send(self, data, length, power):
		if (power<2 or power > 20):
			return False	#Dangerous power levels

		oldMode = self.mode
		
		# Copy into TX buffer
		self.txBuf = data
		self.txBufLen = length

		# Start Transmitter
		print ("OLD MODE: %d" % self.mode)
		self.set_mode(registers["RFM69_MODE_TX"])
		print ("NEW MODE: %d" % self.mode)

		#Setup PA
		if (power <= 17):
			# Set PA Level
			self.paLevel = power + 14
			self.spi_write(registers["RFM69_REG_11_PA_LEVEL"], registers["RF_PALEVEL_PA0_OFF"] | registers["RF_PALEVEL_PA1_ON"] | registers["RF_PALEVEL_PA2_ON"] | self.paLevel )
		else:
			# Disable Over Current Protection
			self.spi_write(registers["RFM69_REG_13_OCP"], registers["RF_OCP_OFF"])
			# Enable High Power Registers
			self.spi_write(registers["RFM69_REG_5A_TEST_PA1"], 0x5D)
			self.spi_write(registers["RFM69_REG_5C_TEST_PA2"], 0x7C)
			# Set PA Level
			self.paLevel = power + 11
			self.spi_write(registers["RFM69_REG_11_PA_LEVEL"], registers["RF_PALEVEL_PA0_OFF"] | registers["RF_PALEVEL_PA1_ON"] | registers["RF_PALEVEL_PA2_ON"] | self.paLevel )

		# Wait for PA ramp-up
		print ("Waiting for PA ramp-up")
		while((self.spi_read(registers["RFM69_REG_27_IRQ_FLAGS1"]) & registers["RF_IRQFLAGS1_TXREADY"]) != registers["RF_IRQFLAGS1_TXREADY"]):
			pass

		# Transmit
		self.write_fifo(self.txBuf)

		# Wait for packet to be sent
		print ("Waiting for packet to be sent")
		while ((self.spi_read(registers["RFM69_REG_28_IRQ_FLAGS2"]) & registers["RF_IRQFLAGS2_PACKETSENT"]) != registers["RF_IRQFLAGS2_PACKETSENT"]):
			pass

		# Return Transceiver to original mode
		print ("OLD MODE: %d" % self.mode)
		self.set_mode(oldMode)
		print ("NEW MODE: %d" % self.mode)

		# If we were in high power, switch off High Power Registers
		if (power > 17):
			self.spi_write(registers["RFM69_REG_5A_TEST_PA1"], 0x55)
			self.spi_write(registers["RFM69_REG_5C_TEST_PA2"], 0x70)
			self.spi_write(registers["RFM69_REG_13_OCP"], (registers["RF_OCP_ON"] | registers["RF_OCP_TRIM_95"]))

		# Clear TX buffer
		self.txBufLen = 0
		self.txBuf = bytearray(registers["RFM69_MAX_MESSAGE_LEN"])

		print ("Transmission complete!")

	def setLnaMode(self, lnaMode):
		self.spi_write(registers["RFM69_REG_58_TEST_LNA"], lnaMode)

	def clearFifo(self):
		self.set_mode(registers["RFM69_MODE_STDBY"])
		self.set_mode(registers["RFM69_MODE_RX"])

	def readTemp(self):
		oldMode = self.mode

		self.set_mode(registers["RFM69_MODE_STDBY"])

		self.spi_write(registers["RFM69_REG_4E_TEMP1"], registers["RF_TEMP1_MEAS_START"])

		print ("Temp Measurement Running")
		while (self.spi_read(registers["RFM69_REG_4E_TEMP1"]) == registers["RF_TEMP1_MEAS_RUNNING"]):
			pass

		rawTemp = self.spi_read(registers["RFM69_REG_4F_TEMP2"])

		self.set_mode(oldMode)

		return (168 - rawTemp) - 5 # Offset and compensate for self-heating

	def lastRssi(self):
		return self.lastRssi

	def sampleRssi(self):
		# Must only be called in RX mode
		if (self.mode != registers["RFM69_MODE_RX"]):
			# Not sure what happens otherwise, so check this
			return 0

		# Trigger RSSI Measurement
		self.spi_write(registers["RFM69_REG_23_RSSI_CONFIG"], registers["RF_RSSI_START"])

		# Wait for Measurement to complete
		print ("Wait for RSSI")
		while((self.spi_read(registers["RFM69_REG_23_RSSI_CONFIG"]) & registers["RF_RSSI_DONE"]) != registers["RF_RSSI_DONE"]):
			pass

		# Read, store in _lastRssi and return RSSI Value
		self.lastRssi = -(self.spi_read(registers["RFM69_REG_24_RSSI_VALUE"])/2)
		return self.lastRssi

	# Read/Write Functions
	def spi_read(self, register):
		data = bytearray(2)
		data[0] = register & ~0x80
		data[1] = 0
		resp = bytearray(2)
		self.nss.low()
		self.spi.send_recv(data, resp, timeout=5000)
		self.nss.high()
		return resp[1]

	def spi_burst_read(self, register, length):
		data = bytearray(length+1)
		data[0] = register & ~0x80
		for i in range(1,length+1):
			data[i] = 0
		# We get the length again as the first character of the buffer
		buf = bytearray(length+1)
		self.nss.low()
		self.spi.send_recv(data, buf, timeout=5000)
		self.nss.high()
		return buf[1:]

	def spi_write(self, register, value):
		data = bytearray(2)
		data[0] = register | 0x80
		data[1] = value
		self.nss.low()
		self.spi.send(data, timeout=5000) 
		self.nss.high()

	def write_fifo(self, data):
		fifo_data = bytearray(len(data)+2)
		fifo_data[0] = registers["RFM69_REG_00_FIFO"] | 0x80
		fifo_data[1] = len(data)
		for i in range(2,len(data)+2):
			fifo_data[i] = data[i-2]
		self.nss.low()
		self.spi.send(fifo_data, timeout=5000)
		self.nss.high()
Esempio n. 14
0
class SPIFlash:

    """ MicroPython for SPI Flash.
    Parameters
    ----------
    nss : (str) CS pin.
    bus : (int) 1 -> The physical pins of the SPI busses
          1 : (NSS, SCK, MISO, MOSI) = (X5, X6, X7, X8) = (PA4, PA5, PA6, PA7)
          2 : (NSS, SCK, MISO, MOSI) = (Y5, Y6, Y7, Y8) = (PB12, PB13, PB14, PB15)
    mode : SPI.MASTER or SPI.SLAVE.
    baudrate : (int) default=42000000

    Returns
    -------
    None

    Examples
    --------
    >>> import spiflash
    >>> flash = spiflash.SPIFlash()
    """

    def __init__(self, nss='A4', bus=1, mode=SPI.MASTER, baudrate=42000000):
        self.__nss = pyb.Pin(nss)
        self.__nss.init(pyb.Pin.OUT_PP)
        self.__nss.high()
        self.spi = SPI(bus, mode, baudrate=baudrate, polarity=0, phase=0)
        self.__device_id = self.read_id()

    def __generic_command(self, cmd):
        self.__nss.low()
        self.spi.send(cmd)
        self.__nss.high()

    def __write_enable(self):
        self.__generic_command(__SFLASH_WRITE_ENABLE)
        self.__read_status_register()

    def __read_status_register(self):
        """ Status Register bit definitions

            STATUS_REGISTER_BUSY                             0x01
            STATUS_REGISTER_WRITE_ENABLED                    0x02
            STATUS_REGISTER_BLOCK_PROTECTED_0                0x04
            STATUS_REGISTER_BLOCK_PROTECTED_1                0x08
            STATUS_REGISTER_BLOCK_PROTECTED_2                0x10    [SST & Macronix Only]
            STATUS_REGISTER_BLOCK_PROTECTED_3                0x20    [SST & Macronix Only]
            STATUS_REGISTER_AUTO_ADDRESS_INCREMENT           0x40    [SST Only]
            STATUS_REGISTER_BLOCK_PROTECT_BITS_READ_ONLY     0x80    [SST Only]
            STATUS_REGISTER_QUAD_ENABLE                      0x40    [Macronix Only]
            STATUS_REGISTER_WRITE_PROTECT_PIN_ENABLE         0x80    [Macronix Only]
        """
        buf = bytearray(1)
        self.__nss.low()
        self.spi.send_recv(__SFLASH_READ_STATUS_REGISTER, buf)
        self.__nss.high()
        # print('__read_status_register: %s'%ubinascii.hexlify(buf).decode('UTF-8').upper())
        return buf[0]

    def read_id(self):
        """ Read SPI Flash ID. """
        self.wait()

        self.__nss.low()
        self.spi.send(__SFLASH_READ_JEDEC_ID)
        ret = self.spi.recv(3)
        self.__nss.high()

        return ubinascii.hexlify(ret).decode('UTF-8').upper()

    def wait(self, timeout=0):
        """ Wait. """

        while timeout < 1000:
            if self.__read_status_register() == 0:
                return True
            else:
                timeout += 1
        return False

    def sector_erase(self, addr):
        """ Sector Erase. """
        self.__write_enable()
        self.__nss.low()
        self.spi.send(__SFLASH_SECTOR_ERASE)
        self.spi.send(bytearray([(addr&0x00FF0000)>>16, (addr&0x0000FF00)>>8, addr&0x000000FF]))
        self.__nss.high()
        return self.__read_status_register()

    def chip_erase(self):
        """ Chip Erase. """
        self.__write_enable()
        self.__generic_command(__SFLASH_CHIP_ERASE2)
        return self.__read_status_register()

    def write(self, addr, buf):
        """ Write data to flash. """
        pos = 0
        write_size = len(buf)
        max_write_size = self.page_size()

        while pos < write_size:
            size = min(write_size-pos, max_write_size)
            self.__write_enable()

            self.__nss.low()
            self.spi.send(__SFLASH_WRITE)
            self.spi.send(bytearray([(addr&0x00FF0000)>>16, (addr&0x0000FF00)>>8, addr&0x000000FF]))
            self.spi.send(buf[pos:pos+size])
            self.__nss.high()

            self.wait()
            addr += size
            pos += size
        return True

    def read(self, addr, size):
        """ Read data from flash. """
        self.__nss.low()
        self.spi.send(__SFLASH_READ)
        self.spi.send(bytearray([(addr&0x00FF0000)>>16, (addr&0x0000FF00)>>8, addr&0x000000FF]))
        ret = self.spi.recv(size)
        self.__nss.high()
        return ret

    def chip_size(self):
        """ Get flash size. """
        try:
            return SFLASH_ID_SIZE[self.__device_id]
        except KeyError:
            return 0

    def page_size(self):
        """ Read Page Size.
        Parameters
        ----------

        Returns
        -------
        Flash page size.

        Examples
        --------
        >>> spi.page_size()
        128
        """
        # Some manufacturers support programming an entire page in one command.
        try:
            return SFLASH_PAGE_SIZE[self.__device_id[:2]]
        except KeyError:
            return 1
Esempio n. 15
0
class SerialFlash25:
    """Class to communicate Serial Flash Memory 25xxxx series with."""
    def __init__(self,
                 name: str,
                 size: int,
                 page_size: int,
                 addr_bytes_num: int,
                 spi: int,
                 cs: str,
                 wp: str,
                 block_size=None,
                 sector_size=None,
                 is_chip_erase=False,
                 conn_chk: bool = False) -> None:
        self.name = name
        self.size = size
        self.sector_size = sector_size
        self.block_size = block_size
        self.page_size = page_size
        self.addr_bytes_num = addr_bytes_num
        self.cs = Pin(cs, Pin.OUT_PP)
        self.wp = Pin(wp, Pin.OUT_PP)
        self.spi = SPI(spi, SPI.MASTER, prescaler=128, polarity=0, phase=0)
        self.conn_chk = conn_chk
        self.is_chip_erase = is_chip_erase
        self._pages_count = size // page_size
        self._sectors_count = size // sector_size if sector_size is not None else None
        self._blocks_count = size // block_size if block_size is not None else None

    @_is_available()
    def read_id(self) -> str:
        """Read device JEDEC Id."""
        self.cs.value(False)
        result = bytearray(4)
        self.spi.send_recv(bytearray([CMD_RDID] + [DUMMY_BYTE] * 3),
                           result)  # Id always contains 3 bytes
        self.cs.value(True)
        res_id = " ".join(["0x%02X" % x for x in result[1:]])
        if res_id == "0x00 0x00 0x00":
            raise RuntimeError(
                "Either IC is connected incorrectly "
                "or it doesn't support Read ID (0x%02X) command." % CMD_RDID)
        return res_id

    def dump(self, path: str) -> None:
        """Dump all device contents to binary file."""
        if self.conn_chk:
            self.read_id()
        if self.sector_size is not None:
            read_cnt, read_item_size = self._sectors_count, self.sector_size
        else:
            read_cnt, read_item_size = self._pages_count, self.page_size
        makedirs(dirname(path))
        with open(path, 'wb') as f:
            for i in range(0, read_cnt):
                # dumping is implemented by sectors/pages
                # because it may be impossible to allocate buffer size of full flash
                buf = self.read(i * read_item_size, read_item_size)
                f.write(buf)
                del buf
        log.info("Dump finished. %s image -> %s" % (self.name, path))

    def program(self, path: str):
        """Flash binary to device."""
        if self.conn_chk:
            self.read_id()
        if not isfile(path):
            raise FileNotFoundError("File  not found: '%s'" % path)
        filesize = getsize(path)
        if filesize != self.size:
            raise ValueError(
                "File size (0x%02X bytes) doesn't equal IC size (0x%02X bytes)"
                % (filesize, self.size))
        self.chip_erase()
        with open(path, 'rb') as f:
            for i in range(0, self._pages_count):
                buf = bytearray(f.read(self.page_size))
                self.page_program(i, buf)
        log.info("Program finished. %s image -> %s" % (path, self.name))

    def chip_erase(self) -> None:
        """Erase chip."""
        if self.is_chip_erase:
            self._wait_wip_reset()
            self._write_enable()
            self.cs.value(False)
            self.spi.send(bytearray([CMD_CE]))
            self.cs.value(True)
            self._write_disable()
            self._wait_wip_reset()
        else:
            for i in range(0, self._pages_count):
                self.page_program(i, bytearray([0xFF] * self.page_size))
        log.info("Chip erase finished.")

    @_is_available("sector_size")
    def sector_program(self, sector_num: int, bytebuffer: bytearray) -> None:
        """Program sector with bytes in bytebuffer."""
        bytebuffer_len = len(bytebuffer)
        if sector_num > self._sectors_count:
            raise ValueError(
                "Sector number (%d) is more than total sectors number (%d)." %
                (sector_num, self._sectors_count))
        if bytebuffer_len > self.page_size:
            raise ValueError(
                "Bytebuffer length (%d) is more than sector size (%d)." %
                (len(bytebuffer), self.page_size))
        self.sector_erase(sector_num)
        pages_count = bytebuffer_len // self.page_size
        remain_bytes = bytebuffer_len % self.page_size
        if remain_bytes != 0:
            log.warning("sector_program: Bytebuffer is not sector aligned.")
        start_page = sector_num * self.sector_size // self.page_size
        for i in range(0, pages_count):
            self.page_program(
                start_page + i,
                bytebuffer[self.page_size * i:self.page_size * (i + 1) + 1])
        if remain_bytes != 0:
            self.page_program(start_page + pages_count,
                              bytebuffer[self.page_size * pages_count:])
        log.info('Sector %d program finished.' % sector_num)

    @_is_available("sector_size")
    def sector_erase(self, sector_num: int) -> None:
        """Erase specified sector."""
        if sector_num > self._sectors_count:
            raise ValueError(
                "Sector number (%d) is more than total sectors number (%d)." %
                (sector_num, self._sectors_count))
        addr = sector_num * self.sector_size
        self._wait_wip_reset()
        self._write_enable()
        self.cs.value(False)
        self.spi.send(
            bytearray([CMD_SE]) + addr.to_bytes(self.addr_bytes_num, "big"))
        self.cs.value(True)
        self._write_disable()
        self._wait_wip_reset()
        log.info("Sector %d erase finished." % sector_num)

    @_is_available("block_size")
    def block_erase(self, block_num: int) -> None:
        """Erase specified block."""
        if block_num > self._blocks_count:
            raise ValueError(
                "Block number (%d) is more than total block number (%d)." %
                (block_num, self._blocks_count))
        addr = block_num * self.sector_size
        self._wait_wip_reset()
        self._write_enable()
        self.cs.value(False)
        self.spi.send(
            bytearray([CMD_BE]) + addr.to_bytes(self.addr_bytes_num, "big"))
        self.cs.value(True)
        self._write_disable()
        self._wait_wip_reset()
        log.info("Block %d erase finished." % block_num)

    def read(self, offset: int, size: int) -> bytearray:
        """Read data from specified offset using specified size."""
        if (offset > self.size) or (offset + size > self.size):
            raise ValueError(
                "Read data from 0x%02X-0x%02X is out of range. Max address is 0x%02X."
                % (offset, offset + size, self.size))
        self.cs.value(False)
        self.spi.send(
            bytearray([CMD_READ]) +
            offset.to_bytes(self.addr_bytes_num, "big"))
        result = bytearray(size)
        self.spi.send_recv(bytearray([DUMMY_BYTE] * size), result)
        self.cs.value(True)
        log.info("Data read 0x%02X-0x%02X finished." % (offset, offset + size))
        return result

    def page_program(self, page_num: int, bytebuffer: bytearray) -> None:
        """Program page with bytes in bytebuffer"""
        if page_num > self._pages_count:
            raise ValueError(
                "Page number (%d) is more than total pages number (%d)." %
                (page_num, self._pages_count))
        if len(bytebuffer) > self.page_size:
            raise ValueError(
                "Bytebuffer length (%d) is more than page size (%d)." %
                (len(bytebuffer), self.page_size))
        addr = page_num * self.page_size
        self._wait_wip_reset()
        self._write_enable()
        self.cs.value(False)
        self.spi.send(
            bytearray([CMD_PP]) + addr.to_bytes(self.addr_bytes_num, "big"))
        self.spi.send(bytebuffer)
        self.cs.value(True)
        self._write_disable()
        self._wait_wip_reset()
        log.info('Page %d program finished.' % page_num)

    def _wait_wip_reset(self) -> None:
        """Wait for WIP=0. WIP is bit0 in Status Register."""
        sr = self.read_sr()
        while sr & SR_WIP:
            sr = self.read_sr()

    def _write_enable(self) -> None:
        """Enable Write operation via command."""
        self.cs.value(False)
        self.spi.send(bytearray([CMD_WREN]))
        self.cs.value(True)

    def _write_disable(self) -> None:
        """Disable Write operation via command."""
        self.cs.value(False)
        self.spi.send(bytearray([CMD_WRDI]))
        self.cs.value(True)

    def read_sr(self):
        """Read status register."""
        result = bytearray(2)
        self.cs.value(False)
        self.spi.send_recv(bytearray([CMD_RDSR, DUMMY_BYTE]), result)
        self.cs.value(True)
        return result[1]

    def write_sr(self, sr_val: int) -> None:
        """Write status register."""
        self._write_enable()
        self.cs.value(False)
        self.spi.send(bytearray([CMD_WRSR, sr_val & 0xFF]))
        self.cs.value(True)
        self._write_disable()
Esempio n. 16
0
# See pyb.UART.

from pyb import UART

uart = UART(1, 9600)
uart.write("hello")
uart.read(5)  # read up to 5 bytes

# SPI bus

from pyb import SPI

spi = SPI(1, SPI.CONTROLLER, baudrate=200000, polarity=1, phase=0)
spi.send("hello")
spi.recv(5)  # receive 5 bytes on the bus
spi.send_recv("hello")  # send and receive 5 bytes

# I2C bus

from machine import I2C

i2c = I2C("X", freq=400000)  # create hardware I2c object
i2c = I2C(scl="X1", sda="X2", freq=100000)  # create software I2C object

i2c.scan()  # returns list of peripheral addresses
i2c.writeto(0x42, "hello")  # write 5 bytes to peripheral with address 0x42
i2c.readfrom(0x42, 5)  # read 5 bytes from peripheral

i2c.readfrom_mem(
    0x42, 0x10, 2)  # read 2 bytes from peripheral 0x42, peripheral memory 0x10
i2c.writeto_mem(