Как стать автором
Обновить

WinnerMicro Wi-Fi SoC W801/W806 (SPI, I2C – дисплей и температура)

Уровень сложностиПростой
Время на прочтение4 мин
Количество просмотров3.2K

Пробуем завести SPI и I2C на китайском чипе WinnerMicro Wi-Fi SoC W801/W806. Подключение дисплея на ST7789 и датчика температуры и влажности AHT10.

Подготовка

Качаем отсюда CDK (IDE)

Регистрация бесплатная, быстрая – только по почте. Скачивается быстро.

Гиты с SDK. Отличия в модуле RF и в некоторых пинах (см. в Литература и прочее).

Для 806

Для 801

Подготовка программатора cklink-lite (если нет)

В качестве отладчика можно использовать BluePill STM32(STM32F103C8T6). Качаем этот проект:

GitHub

И, нужно зашить CKLinkLite2.30.hex в плату. Можно это сделать стандартными STM32 Utility или Cube Programmer.

Стоит заменить драйвер через Zadig, иначе IDE будет ругать вас и грозить пальчиком. Меняем на libusb

Подключение STM32 к W806/801 следующее:

Подключаем самоделкин программатор

Не уверен, что nRESET подключен правильно, т.к сброса не происходит по кнопке, но отлаживать можно.

Чтобы IDE правильно готовила прошивки, нужно воспользоваться файлом W806_Flash_Tool.elf

Заходим во вкладку Flash Management в IDE

Нажимаем Add

Выбираем скачанный ранее файл

И перед закрытием окна, нужно по нему кликнуть. В нижнем окне должен отобразиться выбранный файл.

Далее, во вкладку Configure Flash Tool

Нажимаем Add

Выбираем добавленный ранее драйвер, кликаем Add

Он должен отобразиться вот таким образом в окне устройств

Далее – в этом же окне переходим во вкладку Debug и жмем Settings…

И выставляем галочку Download to Flash

Зашиваем – все прошло гладко. Код адекватно загружается и останавливается на брейкпоинтах.

Ограничения

Вот такое окно может вылезать при ребуте программатора. Видимо, какой-то сервис не отпускает драйвер.

Такое лечится переустановкой драйвера в ручную.

Диспетчер устройств->двойной клик по программатору->Драйвер->Обновить драйвер->Найти на этом компьютере->Выбрать драйвер из списка доступных.

Там будет парочка. Я тыкаю любой, проблема исчезает до следующего перезапуска. Как говорили классики кинематографа: “А большего мне и не надо!”.

При использовании 806 на 801 прошивка не сохраняется после перезагрузки. Не разбирался, не интересно.

После заливки прошивка может не стартануть – нужно зайти в отладку, потом будет нормально.

Это все, что нужно для начала работы.

Заводим SPI на W806/W801

Для открытия проекта со всеми зависимостями, нужно открыть что-то вроде подобного в папке SDK.

WM_SDK_W806\tools\W806\projects\SDK_Project\project\CDK_WS

Пробуем поднять SPI. Узнаем, что их несколько – обычный(LSPI), скоростной(HSPI) и QSPI.

Нам нужен LSPI. Открываем Chip Specifications W801

Видим, что LSPI можно ремапить на следующие ножки порта B:

  • 23 – CS (NSS)

  • 24 – CK (CLK)

  • 25 – MISO

  • 26 – MOSI

Пишем инициализацию.

static HAL_StatusTypeDef SPI_Init(SPI_HandleTypeDef *hspi){
    SPI_InitTypeDef spi;
    HAL_StatusTypeDef ret = HAL_OK;
    //__HAL_AFIO_REMAP_SPI_CS(GPIOB, GPIO_PIN_4); hardware NSS disabeled
    __HAL_AFIO_REMAP_SPI_CLK(GPIOB, SPI_SCL);
    //__HAL_AFIO_REMAP_SPI_MISO(GPIOB, SPI_MISO);
    __HAL_AFIO_REMAP_SPI_MOSI(GPIOB, SPI_MOSI);

    
    hspi->Init.Mode = SPI_MODE_MASTER;
    hspi->Init.CLKPolarity = SPI_POLARITY_HIGH;
    hspi->Init.CLKPhase = SPI_PHASE_1EDGE;
    hspi->Init.NSS = SPI_NSS_SOFT;
    hspi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
    hspi->Init.FirstByte = SPI_LITTLEENDIAN;
    
    hspi->Instance = SPI;
    
    ret = HAL_SPI_Init(hspi);
    return ret;

}

В main вызываем эту функцию и пробуем отправить ( HAL_SPI_Transmit(&hspi1, data, 5, 10000); ) и… тишина.

Проверил код HAL_SPI_Init – все в порядке. Посмотрел какие нужны регистры для работы LSPI – нет ли регистра ENABLE. Нет, все нормально. Может нужно инициализировать ножки? Попробовал – нет. Посмотрел регистр питания – там ничего нет про периферию.

Тактирование смотрел в последнюю очередь(не делайте так), т.к. глаз зацепился за эту фразу при беглом осмотре документации:

В итоге решил вычитать Software Clock Gating Enable Register (HR_CLK_BASE_ADDR) по адресу 0x40000E00 и увидел, что клоки отключены! Включены только для gpio и uart. Первая же функция(SystemClock_Config(CPU_CLK_160M)) выключила всю периферию!

Включаем!

В Register Manual видим, что нужно установить 1 сюда:

i2c
i2c
spi
spi

То есть по маске 0x80 и 0x01 в HR_CLK_BASE_ADDR.

*((uint32_t *)(HR_CLK_BASE_ADDR)) |= CLK_GATE_SPI_MASK|CLK_GATE_I2C_MASK;

И, о чудо, тестовая строка побежала! Пробуем функции от библиотеки дисплея – работает.

SPI – пишем в драйвер дисплея:

Хочу заметить, что если сконфигурировать SPI в BIGENDIAN, то HAL-функция будет работать отвратительно – она для этого не предназначена.

Заводим I2C на W806/W801

Добавляем инициализацию I2C

static HAL_StatusTypeDef I2C_Init(I2C_HandleTypeDef *hi2c){
    HAL_StatusTypeDef ret = HAL_OK;
    __HAL_AFIO_REMAP_I2C_SCL(GPIOB, I2C_SCL);
    __HAL_AFIO_REMAP_I2C_SDA(GPIOB, I2C_SDA);
    hi2c->Frequency = 100000;
    hi2c->Instance = I2C;
    ret = HAL_I2C_Init(hi2c);
    return ret;
}

Сама функция HAL выглядит похоже на STMовскую, но передаваемые параметры немного другие. Немного это меня задержало – не посмотрел сразу

Вот пример отличия:

HAL_StatusTypeDef HAL_I2C_Write(I2C_HandleTypeDef *hi2c, uint8_t DevAddress, uint8_t MemAddress, uint8_t *pData, uint16_t Size); //W800
HAL_StatusTypeDef HAL_I2C_Master_Transmit (I2C_HandleTypeDef* hi2c, uint16_t DevAddress, uint8_t* pData, uint16_t Size, uint32_t Timeout); //STM32

I2C – запрос на чтение с датчика AHT10

Ответ от датчика AHT10

Итоги

Добавил простое рисование факториала в проект и смотрю как рисуется.

Рисуем множество Мандельброта:

Пара тестовых видео:

Проект на GitHub

Литература и полезное прочее

Здесь показано как изображения конвертировать

Скрипт на питоне для перевода вывода программы LCD image converter в вид двумерного массива, который удобно использовать в header’ах.

file1 = open('inp_file.txt', 'r')
file2 = open('test_out.txt', 'w+')
count = 0
file2.write("const uint16_t test_img[][240] = {")
while True:
    line = file1.readline()
    if not line:
        file2.write("};")
        break
    if count != 0:
        file2.write(",")
    count += 1
    file2.write("{" + line + "}")
file2.close()
file1.close()

Практически вся нужная информация по чипам собрана в этом репозитории

GitHub

Ссылка на китайские даташиты на W801

Тут есть про отличия и подключение

Гит с драйвером дисплея на st7789 для STM32

GitHub

Про отладчик

Видос (на китайском) как чел подключает свой программатор на STM32F103 и настраивает запуск отладки (自制CKlink阿里平头哥w801/w806仿真器DIY全教程)

Программаторы самодельные с инструкциями на китайском с готовыми схематиками и разводками:

https://oshwhub.com/jiaminghui98/mini-CKLink

https://oshwhub.com/l88889686/cklinkw80x-fang-zhen-qi

Полу-переведенный даташит на английский на W806:

W806_-1Скачать

Про 806 на easyelectronics

На другом сайте про W806/W801 с полезными ссылками

Теги:
Хабы:
Всего голосов 10: ↑10 и ↓0+10
Комментарии1

Публикации

Истории

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань