MaixAmigo のハードウェア

# MaixCubeのハードウェアについて

回路図: https://dl.sipeed.com/MAIX/HDK/Sipeed-Amigo/Maix_Amigo_2960(Schematic).pdf

![MaixAmigo1.png](https://maixpy.sipeed.com/dev/assets/hardware/maix_amigo/sipeed_maix_amigo_vi.png)

# 3色LED

ケース左下に小さな穴が3つ開いているが、ここに3色LEDが入っている。左上のスイッチでR、G、Bそれぞれに点灯させるサンプル

スイッチは、MaixCubeではレバースイッチが使用されていたが、MaixAmigoはBACK/NEXTのシーソースイッチとENTERのボタンの組み合わせになっている。

```python
import utime
from Maix import GPIO
from board import board_info
from fpioa_manager import fm

LED_R = 14
LED_G = 15
LED_B = 17
LED_W = 32

BACK = 31
ENTER = 23
NEXT = 20

fm.register(LED_R, fm.fpioa.GPIOHS0, force=True)
fm.register(LED_G, fm.fpioa.GPIOHS1, force=True)
fm.register(LED_B, fm.fpioa.GPIOHS2, force=True)
fm.register(BACK, fm.fpioa.GPIO0, force=True)
fm.register(ENTER, fm.fpioa.GPIO1, force=True)
fm.register(NEXT, fm.fpioa.GPIO2, force=True)

led_r = GPIO(GPIO.GPIOHS0, GPIO.OUT)
led_g = GPIO(GPIO.GPIOHS1, GPIO.OUT)
led_b = GPIO(GPIO.GPIOHS2, GPIO.OUT)
input0 = GPIO(GPIO.GPIO0, GPIO.IN)
input1 = GPIO(GPIO.GPIO1, GPIO.IN)
input2 = GPIO(GPIO.GPIO2, GPIO.IN)

i = 0
status = 0
while i<20:
    print("-----input0:", input0.value())
    print("-----input1:", input1.value())
    print("-----input2:", input2.value())
    led_r.value(input0.value())
    led_g.value(input1.value())
    led_b.value(input2.value())
    i+=1
    utime.sleep_ms(500)

fm.unregister(LED_R, fm.fpioa.GPIOHS0)
fm.unregister(LED_G, fm.fpioa.GPIOHS1)
fm.unregister(LED_B, fm.fpioa.GPIOHS2)
fm.unregister(BACK, fm.fpioa.GPIO0)
fm.unregister(ENTER, fm.fpioa.GPIO1)
fm.unregister(NEXT, fm.fpioa.GPIO2)

```

# 白色LED

ENTERキーを押すと背面のカメラの横についている白色LEDが点灯する

```python
import utime
from Maix import GPIO
from board import board_info
from fpioa_manager import fm

ENTER = 23
WLED_EN = 32

fm.register(WLED_EN, fm.fpioa.GPIOHS0, force=True)
fm.register(ENTER, fm.fpioa.GPIO0, force=True)

wled_en = GPIO(GPIO.GPIOHS0, GPIO.OUT)
input = GPIO(GPIO.GPIO0, GPIO.IN)

i = 0
status = 0
while i<20:
    print("-----input:", input.value())
    wled_en.value(input.value())
    i+=1
    utime.sleep_ms(500)

fm.unregister(WLED_EN, fm.fpioa.GPIOHS0)
fm.unregister(ENTER, fm.fpioa.GPIO0)

```

# I2C

アドレス

- 16(10H) - ES8374 サウンド
- 38(26H) - MSA301 加速度センサー
- 52(34H) - AXP173 電源管理
- 56(38H) - FT6X36 タッチセンサー


# 加速度センサー (MSA301)

- チップはMaixCubeと同じ
- I2CはSDA 27、SCL 24とMaixCubeと異なる

```python
import time
from machine import I2C

MSA301_CMD  = 0
MSA301_DATA = 1
MSA301_ADDR = 0x26

def acc_init(i2c):
    partID = i2c.readfrom_mem(MSA301_ADDR, 0x01, 1, mem_size=8)
    if (partID != b'\x13'):
        print("MSA301 not found")
    i2c.writeto_mem(MSA301_ADDR, 0x11, 0x0E, mem_size=8) # power_mode: normal

def acc_read(i2c):
    accX = i2c.readfrom_mem(MSA301_ADDR, 0x02, 2, mem_size=8)
    accY = i2c.readfrom_mem(MSA301_ADDR, 0x04, 2, mem_size=8)
    accZ = i2c.readfrom_mem(MSA301_ADDR, 0x06, 2, mem_size=8)
    print("x=", int.from_bytes(accX, 'little') / 4,
        "y=", int.from_bytes(accY, 'little') / 4,
        "z=", int.from_bytes(accZ, 'little') / 4)


i2c = I2C(I2C.I2C0, mode=I2C.MODE_MASTER, freq=400000, scl=24, sda=27, addr_size=7)

time.sleep(1)
acc_init(i2c)
while True:
    acc_read(i2c)
    time.sleep(1)

```

# 電源管理 (AXP173)

- チップはMaixCubeと同じ
- I2CはSDA 27、SCL 24とMaixCubeと異なる
- バッテリーの容量がMaixCubeより大きい（MaixCube 190mAh、MaixAmigo 520mAh）
- MaixCubeで使用していなかったLDO3、LDO4を使用している模様（回路図ではLDO4はカメラに供給されている）

# フラッシュメモリ (W25QXX)

MaixAmigoは16Mバイトのフラッシュメモリが内蔵されていて、MaixPyでは上位3MバイトをSPIFFSとして利用できるようになっています。初期状態でこのようなファイルが格納されていました。

```
bme280.py
button.py
camera.py
config.json
es8374.py
face_reco.py
freq.conf
fs.py
led.py
msa301.py
pmu_axp173.py
qmcx983.py
shtxx.py
sound.py
test.wav
ui_canvas.py
ui_catch.py
wdt.py
main.py

```

例えばこんな感じ

```python:main.py
try:
    import os, Maix, lcd, image
    gc.collect()
    lcd.init()
    loading = image.Image(size=(lcd.width(), lcd.height()))
    loading.draw_rectangle((0, 0, lcd.width(), lcd.height()), fill=True, color=(255, 0, 0))
    info = "Welcome to MaixPy"
    loading.draw_string(int(lcd.width()//2 - len(info) * 5), (lcd.height())//4, info, color=(255, 255, 255), scale=2, mono_space=0)
    v = sys.implementation.version
    vers = 'V{}.{}.{} : maixpy.sipeed.com'.format(v[0],v[1],v[2])
    loading.draw_string(int(lcd.width()//2 - len(info) * 6), (lcd.height())//3 + 20, vers, color=(255, 255, 255), scale=1, mono_space=1)
    lcd.display(loading)
finally:
    del loading, v, info, vers
    gc.collect()

```

# サウンド (ES8374)

SPIFFSにサンプルコード、サンプルのwavが格納されているので、MaixPy IDEからsound.pyの113行目を修正して実行します。ノイズもなく綺麗な音がでます。

```python
from es8374 import ES8374
from Maix import I2S
from fpioa_manager import *
import audio
import time
# from machine import Timer


class CubeAudio:

    i2c, i2s, dev = None, None, None

    # tim = Timer(Timer.TIMER0, Timer.CHANNEL0, start=False, mode=Timer.MODE_PERIODIC, period=15, callback=lambda:None)

    def init(i2c_dev=None):
        CubeAudio.i2c = i2c_dev

    def check():
      if CubeAudio.i2c != None:
        return ES8374._ES8374_I2CADDR_DEFAULT in CubeAudio.i2c.scan()
      return False

    player, is_load, is_ready = None, False, False

    def ready(is_record=False, volume=100):
      CubeAudio.is_ready = CubeAudio.is_load = False
      if CubeAudio.check():
        if CubeAudio.dev != None:
            CubeAudio.dev.stop(0x02)
        CubeAudio.dev = ES8374(CubeAudio.i2c)
        CubeAudio.dev.setVoiceVolume(volume)
        CubeAudio.dev.start(0x03)
        CubeAudio.i2s = I2S(I2S.DEVICE_0, pll2=262144000, mclk=31)
        if is_record:
            CubeAudio.i2s.channel_config(I2S.CHANNEL_0, I2S.RECEIVER, resolution=I2S.RESOLUTION_16_BIT,
                                         cycles=I2S.SCLK_CYCLES_32, align_mode=I2S.STANDARD_MODE)
        else:
            CubeAudio.i2s.channel_config(I2S.CHANNEL_2, I2S.TRANSMITTER, resolution=I2S.RESOLUTION_16_BIT,
                                         cycles=I2S.SCLK_CYCLES_32, align_mode=I2S.STANDARD_MODE)
        CubeAudio.is_ready = True
      return CubeAudio.is_ready

    def load(path, volume=100):
        if CubeAudio.player != None:
            CubeAudio.player.finish()
            # CubeAudio.tim.stop()
        CubeAudio.player = audio.Audio(path=path)
        CubeAudio.player.volume(volume)
        wav_info = CubeAudio.player.play_process(CubeAudio.i2s)
        CubeAudio.i2s.set_sample_rate(int(wav_info[1]))

        CubeAudio.is_load = True
        # CubeAudio.tim.callback(CubeAudio.event)
        # CubeAudio.tim.start()
        #time.sleep_ms(1000)

    def event(arg=None):
        if CubeAudio.is_load:
            ret = CubeAudio.player.play()
            if ret == None or ret == 0:
                CubeAudio.player.finish()
                time.sleep_ms(50)
                # CubeAudio.tim.stop()
                CubeAudio.is_load = False
            return True
        return False


if __name__ == "__main__":
    from machine import I2C
    # fm.register(24, fm.fpioa.I2C1_SCLK, force=True)
    # fm.register(27, fm.fpioa.I2C1_SDA, force=True)
    #fm.register(30,fm.fpioa.I2C1_SCLK, force=True)
    #fm.register(31,fm.fpioa.I2C1_SDA, force=True)

    i2c = I2C(I2C.I2C3, freq=600*1000, sda=27, scl=24)  # amigo
    CubeAudio.init(i2c)
    tmp = CubeAudio.check()
    print(tmp)
    if (tmp):
        # cube
        #fm.register(19,fm.fpioa.I2S0_MCLK, force=True)
        #fm.register(35,fm.fpioa.I2S0_SCLK, force=True)
        #fm.register(33,fm.fpioa.I2S0_WS, force=True)
        #fm.register(34,fm.fpioa.I2S0_IN_D0, force=True)
        #fm.register(18,fm.fpioa.I2S0_OUT_D2, force=True)

        # amigo
        fm.register(13, fm.fpioa.I2S0_MCLK, force=True)
        fm.register(21, fm.fpioa.I2S0_SCLK, force=True)
        fm.register(18, fm.fpioa.I2S0_WS, force=True)
        fm.register(35, fm.fpioa.I2S0_IN_D0, force=True)
        fm.register(34, fm.fpioa.I2S0_OUT_D2, force=True)

        #CubeAudio.ready()
        #while True:
            #CubeAudio.load(path="/sd/res/sound/loop.wav")
            #while CubeAudio.is_load:
                ##time.sleep_ms(20)
                #CubeAudio.event()
                #print(time.ticks_ms())

        #from Maix import GPIO, I2S, FFT
        #import image, lcd, math
        #
        #from fpioa_manager import fm

        sample_rate = 38640
        sample_points = 1024
        #fft_points = 512
        #hist_x_num = 50

        # この部分から修正しました
        # record to wav
        print('play to wav')
        CubeAudio.ready()
        CubeAudio.load("/flash/test.wav")
        while CubeAudio.is_load:
            #time.sleep_ms(20)
            CubeAudio.event()
            print(time.ticks_ms())
              
```
# タッチスクリーン (FT6X36)

MaixPyでサポートされている？手動ビルドが必要？

```python
import time
from machine import I2C

FT6X36_ADDR = 0x38

def ts_init(i2c):
    vendorID = i2c.readfrom_mem(FT6X36_ADDR, 0xA8, 1, mem_size=8)
    print("VendorID", vendorID)
    chipID = i2c.readfrom_mem(FT6X36_ADDR, 0xA3, 1, mem_size=8)
    print("ChipID", chipID)
    if (vendorID != b'\x11'):
        print("FT6X36 not found")
    if (chipID != b'\x06' and chipID != b'\x26' and chipID != b'\x36'):
        print("FT6X36 not found")
    i2c.writeto_mem(FT6X36_ADDR, 0x00, 0x00, mem_size=8) # device_mode: 
    i2c.writeto_mem(FT6X36_ADDR, 0x80,   22, mem_size=8) # threshhold: 
    i2c.writeto_mem(FT6X36_ADDR, 0x88, 0x0E, mem_size=8) # touchrate_active: 

def ts_read(i2c):
    dat = i2c.readfrom_mem(FT6X36_ADDR, 0x00, 16, mem_size=8)
    print(dat)


i2c = I2C(I2C.I2C0, mode=I2C.MODE_MASTER, freq=400000, scl=24, sda=27, addr_size=7)

time.sleep(1)
ts_init(i2c)
while True:
    ts_read(i2c)
    time.sleep(1)

```