Показ дописів із міткою Infineon. Показати всі дописи
Показ дописів із міткою Infineon. Показати всі дописи

неділю, 6 серпня 2023 р.

Огляд Device Configurator в складі ModusToolbox від компанії Infineon

Передмова

Я радий, що ви зацікавилися ModusToolbox 3.1 від компанії Infineon і хочете дізнатися більше про Device Configurator - одну з утиліт, яка входить до складу цього середовища. Я можу допомогти вам з цим, адже я в цьому вже розібрався і я знімаю відео про різні теми, пов’язані з розробкою вбудованих систем. Мій канал на Youtube. Я також пишу статті про мікроконтролери, які можна прочитати на  цьому блозі і на іншому моєму сайті [STM32 without fear].

У цій статті я хочу розповісти вам про Device Configurator - утиліту, яка дозволяє налаштовувати параметри мікроконтролера, такі як GPIO, UART, SPI тощо. Я також хочу показати вам, як використовувати Device Configurator для створення і редагування проекту за допомогою ModusToolbox 3.1.

Device Configurator

Device Configurator - це графічний інтерфейс, який надає доступ до всіх налаштувань мікроконтролера, який ви обрали для свого проекту. Ви можете запустити Device Configurator з меню Quick Panel:

Виклик Device Configurator для поточного проекту

  1. Вкладка "Project Explorer",
  2. Ваш проект має бути обраним,
  3. Вкладка панелі швидкого доступу "Quick Panel"
  4. Виклик Device Configurator

Або з контекстного меню вашого проекту:

Виклик Device Configurator із контекстного меню проекту

  1. Права кнопка миші на вашому проекті,
  2. Меню "ModusToolbox"
  3. Виклик "Device Configurator"

Коли ви запускаєте Device Configurator, ви можете бачити такі різні вкладки, які мають різну функціональність:

  • Peripheral - ця вкладка дозволяє включати або виключати периферійні пристрої мікроконтролера, такі як UART, SPI, I2C тощо. Ви також можете налаштовувати параметри кожного периферійного пристрою, такі як швидкість передачі даних, режим роботи, кількість біт тощо.

Device Configurator вкладка Peripheral
  • Pins - ця вкладка дозволяє підключати периферійні пристрої до GPIO (General Purpose Input/Output) - це універсальні контакти мікроконтролера, які можуть слугувати для введення або виведення сигналу. Ви також можете налаштовувати параметри кожного GPIO, такі як напруга, напрямок, опор або пул-ап/пул-даун резистор тощо.

Device Configurator вкладка Pins

  • Analog-Routing - ця вкладка дозволяє побудувати аналоговий сигнальний шлях між периферійними пристроями та GPIO. Ви можете обирати різні компоненти для аналогового сигнального шляху, такі як операційний підсилювач, компаратор, мультиплексор тощо.

Device Configurator вкладка Analog Routing
  • System - ця вкладка дозволяє налаштовувати параметри системи, такі як режим роботи, джерело тактування, частота тактування, обрати потрібні дільники тактування, тощо, для периферії, CPU, RTC.

Device Configurator вкладка System
  • Peripheral-clock - ця вкладка дозволяє налаштовувати параметри годинника для кожного периферійного пристрою. Ви можете обирати різні джерела годинника, такі як IMO (Internal Main Oscillator), ECO (External Crystal Oscillator), WCO (Watch Crystal Oscillator) тощо. Ви також можете налаштовувати частоту годинника і дільник годинника для кожного периферійного пристрою.

Device Configurator вкладка Peripheral Clock

  • DMA - ця вкладка дозволяє налаштовувати параметри DMA (Direct Memory Access) - це технологія, яка дозволяє пересилати дані між пам’яттю і периферійними пристроями без участі процесора. Ви можете створювати і редагувати DMA канали, які визначають джерело і призначення пересилання даних, розмір і кількість блоків даних, умови запуску і зупинки DMA каналу тощо.

Device Configurator вкладка DMA

Одним з корисних функцій Device Configurator є можливість використовувати aliases для GPIO та іншої периферії. Aliases - це символьні назви для GPIO або периферійних пристроїв, які можна використовувати замість числових номерів. Наприклад, ви можете назвати GPIO, який підключений до світлодіода на платі, LED1 або GPIO, який підключений до кнопки на платі, SW1. Це полегшує читання і розуміння коду і схем.

Важливо зауважити, що вкладки периферії на кожному сімействі чипів різні, тому вкладки Device Configurator можуть виглядати по-різному в залежності від обраної платформи. Наприклад, якщо ви обрали плату CY8CKIT-062-WIFI-BT, яка має мікроконтролер PSoC6, то ви будете мати такі вкладки периферії, як зображено вище.

Це все, що я хотів сказати про Device Configurator у цій статті. Я сподіваюся, що вам сподобалось і вам стало цікаво спробувати цю утиліту для налаштування мікроконтролера. Якщо у вас є питання або коментарі, будь ласка, пишіть їх у коментарях під статтею. Я буду радий вам відповісти. Дякую за читання і до нових зустрічей!

Відео матеріали





неділю, 23 липня 2023 р.

Огляд ModusToolbox 3.1 від компанії Infineon

 Передмова

Радіймо друзі з вами Андрій і в цій статті ми поговоримо про нову версію ModusToolbox 3.1 від компанії Infineon. ModusToolbox 3.1 - це комплексне програмне середовище для розробки вбудованих систем на базі мікроконтролерів Infineon. ModusToolbox надає розробникам гнучкість і ефективність при створенні програм для різних платформ і застосувань. ModusToolbox також містить багато корисних утиліт і бібліотек, які дозволяють легко налаштовувати і оптимізувати роботу мікроконтролерів. В цій статті я розгляну, як завантажити і встановити ModusToolbox 3.1, як створити новий проект для Eclipse IDE for ModusToolbox, та для Visual Studio Code.

Завантаження і встановлення

Для того, щоб завантажити і встановити ModusToolbox 3.1, нам потрібно спочатку завантажити Infineon Developer Center launcher. Це програма, яка дозволяє вибрати і встановити різні продукти від Infineon, включаючи ModusToolbox 3.1. Ми можемо завантажити Infineon Developer Center launcher з офіційного сайту Infineon. Після завантаження ми запускаємо Infineon Developer Center launcher і бачимо таке вікно:

Завантаження і інсталювання ModusToolbox за допомоги Developer Center

Тут ми можемо вибрати ModusToolbox 3.1 і натиснути на кнопку Install. Програма запропонує нам вказати шлях для встановлення ModusToolbox 3.1 і погодитись з ліцензійною угодою. Після цього почнеться процес встановлення ModusToolbox 3.1, який може тривати деякий час.

Коли встановлення закінчиться, ми можемо перевірити, що ModusToolbox 3.1 успішно встановлено, натиснувши на кнопку Start. Ми також можемо повернутися до Infineon Developer Center launcher і побачити, що тепер у нас є можливість запустити або вилучити ModusToolbox 3.1.

За допомогою Infineon Developer Center launcher ми також можемо завантажити інші корисні речі. Для цього ми можемо натиснути на кнопку Manage Tools і обрати потрібний пункт.

Огляд компонентів і утиліт

Тепер, коли ми завантажили і встановили ModusToolbox 3.1, давайте розберемося з термінологією, яку використовує це середовище.

ModusToolbox 3.1 - це не просто одна програма, а набір різних компонентів, які спільно працюють для розробки вбудованих систем. Одним з головних компонентів є Eclipse IDE for ModusToolbox- це інтегроване середовище розробки (IDE), яке базується на Eclipse і має всі необхідні функції для створення, редагування, компіляції, налагодження проекту. Eclipse IDE for ModusToolbox також має вбудований термінал, який дозволяє спілкуватися з мікроконтролером за допомогою UART або SWD. Eclipse IDE for ModusToolbox підтримує мови програмування, такі як C, C++ тощо.

Eclipse IDE for ModusToolbox

Іншим важливим компонентом є ModusToolbox assistants - це набір плагінів для Visual Studio Code, який дозволяє створювати і редагувати проекти за допомогою цього популярного редактора коду. ModusToolbox assistants мають ті ж функції, що і Eclipse IDE for ModusToolbox. Щоб використовувати ModusToolbox assistants, нам потрібно встановити ModusToolbox 3.1, Visual Studio Code і додати плагіни Eclipse IDE for ModusToolbox.

Плагін ModusToolbox Assistant виглядає так

Одним з ключових понять у ModusToolbox 3.1 є board support package (BSP) - це набір файлів і налаштувань, які адаптують проект під конкретну плату або мікроконтролер. BSP містить інформацію про апаратну конфігурацію, периферійні пристрої, тощо. Ми можемо створити свій власний BSP або використати готовий BSP для однієї з доступних плат від Infineon.

BSP Assistant

Тепер, коли ми ознайомилися з термінологією, давайте створимо наш перший проект за допомогою Project Creator. Ми можемо зробити це  для Eclipse IDE for ModusToolbox або Visual Studio Code. У цьому випадку ми скористаємося Eclipse IDE for ModusToolbox, але процес буде схожий і для Visual Studio Code.

Для того, щоб створити новий проект, ми запускаємо Eclipse IDE for ModusToolbox і обираємо File -> New -> ModusToolbox Application.

Тут ми можемо вказати назву нашого проекту, шлях для його розташування. За допомогою Device Configurator налаштовуємо периферію. Device Configurator - це утиліта, яка дозволяє графічно налаштовувати параметри мікроконтролера, такі як GPIO, UART, SPI тощо. За допомоги Library Manager додаємо які саме бібліотеки, драйвери і міделвари будуть входити до складу нашого проекту. Library Manager - це утиліта, яка дозволяє додавати або видаляти бібліотеки, які надають функціональність для різних застосувань, таких як Bluetooth, CapSense, USB тощо. Оберемо Device Configurator.

Device Configurator

Коли проект згенеровано, ми можемо ознайомитися з його структурою. Ми бачимо, що наш проект складається з різних файлів і папок, які мають своє призначення і функцію.

Структура проекту

Основним файлом нашого проекту є main.c - це файл, де ми пишемо код нашої програми. Тут ми можемо використовувати функції з бібліотек, які додаються до нашого проекту за допомогою Library Manager або Device Configurator.

Іншим важливим файлом нашого проекту є design.modus - це файл, де ми можемо налаштовувати параметри мікроконтролера за допомогою Device Configurator. Тут ми можемо графічно визначати, які периферійні пристрої ми хочемо використовувати, яким чином ми хочемо їх налаштовувати і як ми хочемо їх підключати до GPIO. Ми також можемо налаштовувати параметри тактування і інші опції.

Ще одним важливим файлом нашого проекту є makefile - це файл, де ми можемо визначати, як компілювати і налагоджувати проект. Тут ми можемо вказати, який компілятор ми хочемо використовувати, які прапорці/компоненти ми хочемо передавати компілятору, які бібліотеки ми хочемо додати до нашого проекту тощо. Ми також можемо вказати, який інструмент ми хочемо використовувати для налагодження нашого проекту, наприклад, OpenOCD або Segger J-Link.

Тепер, коли ми створили наш проект і ознайомилися з його структурою, давайте подивимося, які утиліти має ModusToolbox 3.1 і як їх використовувати для розробки та налагодження нашого проекту.

ModusToolbox 3.1 має багато корисних утиліт, які дозволяють легко налаштовувати і оптимізувати роботу мікроконтролерів. Деякі з них я вже згадав, наприклад, Device Configurator і Library Manager. Але є ще багато інших утиліт, які можна запустити з меню Tools або з контекстного меню проекту.

Панель швидкого доступу до утиліт і документації

Ось деякі з утиліт, які має ModusToolbox 3.1:

  • CapSense Configurator - це утиліта, яка дозволяє налаштовувати параметри CapSense - це технологія, яка дозволяє використовувати сенсорні кнопки або сенсорні панелі для керування мікроконтролером. За допомогою CapSense Configurator ми можемо визначити, скільки і якого типу сенсорних елементів ми хочемо використовувати, як ми хочемо їх підключити до GPIO і як ми хочемо їх калібрувати та тестувати.

CAPSENSE Configurator

  • Bluetooth Configurator - це утиліта, яка дозволяє налаштовувати параметри Bluetooth - це технологія, яка дозволяє бездротово з’єднуватися з іншими пристроями за допомогою радіосигналу. За допомогою Bluetooth Configurator ми можемо визначити, який профіль Bluetooth ми хочемо використовувати, наприклад, BLE (Bluetooth Low Energy) або BR/EDR (Basic Rate/Enhanced Data Rate), які сервіси і характеристики ми хочемо надавати або використовувати, як ми хочемо рекламувати наш пристрій або знаходити інші пристрої тощо.

Bluetooth Configurator
  • USB Configurator - це утиліта, яка дозволяє налаштовувати параметри USB - це технологія, яка дозволяє підключатися до комп’ютера або інших пристроїв за допомогою кабелю. За допомогою USB Configurator ми можемо визначити, який режим USB ми хочемо використовувати, наприклад, Device (пристрій), Host (господар) або OTG (On-The-Go), які класи USB ми хочемо підтримувати, наприклад, CDC (Communication Device Class), HID (Human Interface Device) або MSC (Mass Storage Class), як ми хочемо ідентифікувати наш пристрій за допомогою VID (Vendor ID) і PID (Product ID) тощо.

USB configurator

Це лише деякі з утиліт, які має ModusToolbox 3.1. Якщо ви хочете детальніше дізнатися про них, ви можете переглянути документацію ModusToolbox 3.1 або приклади коду, які можна завантажити за допомогою Infineon Developer Center launcher.

Це все, що я хотів сказати про ModusToolbox 3.1 в цій статті. Я сподіваюся, що вам сподобалось і вам стало цікаво спробувати це середовище для розробки вбудованих систем. Якщо у вас є питання або коментарі, будь ласка, пишіть їх у коментарях під цією статтєю. Я буду радий вам відповісти. Дякую за перегляд і до нових зустрічей!

Відео матеріали




суботу, 14 травня 2022 р.

MTB: PSoC4 CY8CKIT-045S прочитаємо значення ADC, порухаємо SERVO за допомоги PWM, розберемось з GPIO I/O interrupt

 Передмова

В попередніх статтях "Встановлення ModusToolBox та перший проект на CY8CKIT-149 PSoC® 4100S Plus Prototyping Kit" та "MTB: PSoC4 CY8CKIT-149 дослідимо аналогові блоки ADC та LPCOMP за допомоги PDL" розібрались як встановити MTB, навчились створювати проект для PSoC4 CY8CKIT-149. А також розібрались як налатувати і скористатись такими аналоговими блоками, як ADC і LPCOMP.

 В цьому дописі пропоную спробувати вже PSoC4 CY8CKIT-045S. Плата має ARDUINO сумісний роз'єм і щоб не збирати макет з купою дротів, скористаємось нагодою і спробуємо провести експерименти з мультифункціональною дошкою для ARDUINO сумісного форм-фактору.

Макет для дослідження
Зручно, без дротів, приєднати дошку з різноманітною периферією, до дошки з мікроконтролером і зосередитись на програмуванні. Але все ж таки, ще потрібно додати 2 сервомашинки. Для них є спеціальний роз'єм на дошці з шпильками D7, D8. Все інше, а це: фоторезистор A1, змінний резистор A0, кнопка D2 і світлодіод D12 або D13 є в наявності на платі. Ні паяти, ні припасовувати дроти, не потрібно.

Створюємо проект

Відкриваємо ModusToolBox, створюємо проект, обираємо свій мікроконтролер, в нашому випадку це CY8CKIT-045S:

Обираємо потрібний мікроконтролер
Далі обираємо шаблон проекту як "пустий проект":
Обираємо шаблон проекту

Та даємо назву проекту, наприклад "CY8CKIT-045S_ADC_PWM".
Подвійним кліком миші розгортаємо дерево проекту в провіднику проектів "Project Explorer" відкриваємо головний файл "main.c":
Відкриваємо файл main.c

В панелі швидкого доступу запускаємо "Device Configurator" і займемось налаштуванням потрібної периферії:

ADC

Для цього проекту нам знадобиться один ADC з двома 12-бітними каналами. Шпильки A0, A1 з яких будемо зчитувати аналогові сигнали будуть доступні для ADC1:
Увімкнення ADC
  1. Вмикаємо PASS 1 12-bit SAR ADC 0
  2. Даємо йому псевдонім (Alias), як "ADC_1", тоді зручно буде ним оперувати в коді
Перейдемо до налаштувань ADC, це виглядає таким чином:
Налаштування ADC
  1. Обираємо джерело опорної напруги як Vdda, це буде 3.3V
  2. Встановлюємо два канали (для змінного резистора і фоторезистора)
  3. Обираємо якийсь вільний дільник як джерело тактування
Трішки нижче будуть розділи для налаштування каналів, їх буде 2. Єдине що потрібно зробити це обрати шпильки з яких будемо читати аналоговий сигнал. Це шпильки A0 і A1, тут в BSP вони позначаються як CYBSP_A0 і CYBSP_A1. Обираємо саме їх:
Налаштування каналів ADC
Червоним позначив на що звернути увагу, щоб було так само для нашого, конкретного, прикладу.

PWM

В нашому прикладі-демонстрації, задіяно два сервопривода. Тому налаштуємо два таймери в режимі PWM. Нас цікавлять саме ті таймери в яких є доступ до шпильок D7 і D8, а це "TCPWM 16-bit Counter 4, 5":
Увімкнення двох TCPWM
  1. Активуємо лічильник 4 і 5
  2. Обираємо режим PWM
  3. Даємо їм псевдоніми (Alias) такі як "SERVO1", "SERVO2", надалі в коді буде зручно звертатись до них по псевдоніму
Перед тим як перейдемо до налаштувань PWM, спочатку налаштуємо дільник з якого будуть наші PWM тактуватись. Перейдемо до вкладки "Peripheral-Clock" і оберемо окремий "divider" для потреб PWM:
Налаштування джерела тактування для PWM
  1. Оберемо вільний дільник, в прикладі це "16 bit Devider 2", та дамо йому псевдонім (Alias), як PWM. 
  2. Дивимось яка частота на вхід дільника приходить, в нашому випадку це 48МГц
  3. Назначаємо значення для дільника, як 48, 
  4. На виході дільник буде 1МГц (48МГц/48 = 1МГц). Саме від цієї частоти будуть тактуватись TCPWM.
  5. Спочатку тут ще нічого не буде, тому що від якого дільника тактуватись PWM визначемо в наступному кроці.
Повертаємось до налаштувань PWM, для двох PWM будуть однакові налаштування, то ж покажу як налаштувати один канал PWM, а інший буде мати абсолютно такі ж значення:
Налаштування PWM каналу
  1. Режим таймера PWM
  2. В нашому випадку дільник 1, не рухаємо
  3. Період 19999. Тактуємось від джерела в 1МГц. А для серви потрібна частота 50Гц, а це 0.02 секунди. Тому 1000000*0.02=20000. Так як в лічильник рахує з 0, то 20000-1=19999.
  4. Серва працює від довжини періоду і має крайні значення періоду ~0.5 - 2.5 мілісекунди, а це будуть значення для "Compare" від 500-1=499 до 2500-1=2499. Початкове значення виставляємо не крайове, щоб точно знати що позиція сервомашинки не виходить за межі фізичного обмеження, тому обрав значення як - 999.
  5. От тут вже і обираємо "16 bit Divider 2 clk (PWM)", який ми попередньо налаштували на 1МГц.
  6. Та оберемо саме на які шпильки буде подаватись сигнал PWM, як на малюнках нижче:

GPIO

З вкладки "Peripheral" перейдемо до вкладки "Pins" і налаштуємо дві шпильки. D2 як вхід з перериванням, а D12 на вихід:
Вмикаємо GPIO
Цим шпилькам призначений вже псевдонім (Alias), такий як CYBSP_D12 який відповідає P5_1 шпильці і CYBSP_D2 який відповідає P5_5 шпильці. В коді ми будемо звертатись по псевдонімам до цих шпильок.
Налаштування для кнопки з перериваннями CYBSP_D2 виглядає так:
Налаштування кнопки з перериванням
  1. Режим вхід з підтяжкою до плюса "Resestive Pull-Up. Input buffer on"
  2. Початкове значення високий рівень "High(1)"
  3. Винекниння переривання по спадаючому фронту "Falling Edge"
Налаштування шпильки для світлодіода виглядатиме так:
Налаштування шпильки світлодіода
  1. Режим на вихід "Strong Drive. Input buffer off"
  2. Початкове значення "Low(0)". Світлодіод вимкнено.
З налаштуваннями периферії покінчено, можемо зберегти зміни за допомоги гарячих комбінацій - CTRL+S і перейти до створення коду-демонстрації

Демо-код

Для того щоб було зручно друкувати повідомлення в серіал-термінал за допомоги "printf" потрібно додати бібліотеку "cy_retarget_io.h". Запускаємо "Library manager" і додаємо:
Додаємо "cy_retarget_io"
Робимо всі кроки як на малюнку і перейдемо до кодування нашого демо-проекту. Відкриємо файл "main.c". Початково він виглядатиме так:
#include "cy_pdl.h"
#include "cybsp.h"

int main(void)
{
    cy_rslt_t result;

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    /* Enable global interrupts */
    __enable_irq();

    for (;;)
    {
    }
}
А тепер можна додати демо-код, який я надам нижче. Розписувати кожен рядок не має сенсу, все доволі просто. А кому цікаво, або не зрозумілі якісь деталі то перегляньте відео-посібник в кінці цієї статті, де я відтворю всі кроки створення налаштування та кодування - детальніше.
То ж коли додамо демо-код, то наш файл "main.c" виглядатиме так:
#include "cy_pdl.h"
#include "cybsp.h"
#include "cy_retarget_io.h"
#include <stdbool.h>

#define SERVO_MAX	2399U
#define SERVO_MIN	599U

uint16_t resultADC1[2] = {0};
bool flagSwap = false;

cy_stc_sysint_t intKeyCfg = {
    .intrSrc = CYBSP_D2_IRQ,
    .intrPriority = 3UL
};

int map(int st1, int fn1, int st2, int fn2, int value)
{
    return (int)((float)(value - st1) * (fn2 - st2) / (float)(fn1 - st1) + st2);
}

void servo1_write(int angle)
{
    Cy_TCPWM_PWM_SetCompare0(SERVO1_HW, SERVO1_NUM, map(2047, 0, SERVO_MIN, SERVO_MAX, angle));
}

void servo2_write(int angle)
{
    Cy_TCPWM_PWM_SetCompare0(SERVO2_HW, SERVO2_NUM, map(2047, 0, SERVO_MIN, SERVO_MAX, angle));
}

void KeyISR(void)
{
    Cy_GPIO_Inv(CYBSP_D12_PORT, CYBSP_D12_PIN);
    flagSwap = !flagSwap;
    Cy_SysLib_Delay(50u);
    Cy_GPIO_ClearInterrupt(CYBSP_D2_PORT, CYBSP_D2_PIN);
}

int main(void)
{
    cy_rslt_t result;

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;
    
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);

    if (result != CY_RSLT_SUCCESS)
    {
	CY_ASSERT(0);
    }

    Cy_SysInt_Init(&intKeyCfg, KeyISR);
    NVIC_ClearPendingIRQ(intKeyCfg.intrSrc);
    NVIC_EnableIRQ(intKeyCfg.intrSrc);

    /* Enable global interrupts */
    __enable_irq();

    printf("\x1b[2J\x1b[;H");
    printf("*------------------------------*\r\n");
    printf("*   Demo ADC and PWM started!  *\r\n");
    printf("*------------------------------*\r\n");

    result = Cy_SAR_Init(ADC_1_HW, &ADC_1_config);

    if (result != CY_RSLT_SUCCESS)
    {
	CY_ASSERT(0);
    }

    Cy_SAR_Enable(ADC_1_HW);

    result = Cy_TCPWM_PWM_Init(SERVO1_HW, SERVO1_NUM, &SERVO1_config);

    if (result != CY_RSLT_SUCCESS)
    {
	CY_ASSERT(0);
    }

    result = Cy_TCPWM_PWM_Init(SERVO2_HW, SERVO2_NUM, &SERVO2_config);

    if (result != CY_RSLT_SUCCESS)
    {
	CY_ASSERT(0);
    }

    Cy_TCPWM_PWM_Enable(SERVO1_HW, SERVO1_NUM);
    Cy_TCPWM_PWM_Enable(SERVO2_HW, SERVO2_NUM);
    Cy_TCPWM_TriggerStart(SERVO1_HW, SERVO1_MASK);
    Cy_TCPWM_TriggerStart(SERVO2_HW, SERVO2_MASK);

    for (;;)
    {
    	Cy_SAR_StartConvert(ADC_1_HW, CY_SAR_START_CONVERT_SINGLE_SHOT);
        Cy_SAR_IsEndConversion(ADC_1_HW, CY_SAR_WAIT_FOR_RESULT);
	resultADC1[0] = Cy_SAR_GetResult16(ADC_1_HW, 0);
	resultADC1[1] = Cy_SAR_GetResult16(ADC_1_HW, 1);

	if(flagSwap)
	{
	    servo1_write(resultADC1[1]);
	    servo2_write(resultADC1[0]);
	}
	else
	{
	    servo1_write(resultADC1[0]);
	    servo2_write(resultADC1[1]);
	}

	printf("ADC1 Result Channel 0 = %4d\r\n", resultADC1[0]);
	printf("ADC1 Result Channel 1 = %4d\r\n", resultADC1[1]);
	printf("\x1b[1F");
	printf("\x1b[1F");
	Cy_SysLib_Delay(20);
    }
}
Компілюємо, заливаємо, спостерігаємо. Резистором на A0 крутимо одну серву, а інша серва приймає положення в залежності від освітлення фоторезистора на A1. Кнопкою на D2 міняємо місцями серви.

Відео посібник



суботу, 7 травня 2022 р.

MTB: PSoC4 CY8CKIT-149 дослідимо аналогові блоки ADC та LPCOMP за допомоги PDL

 Передмова

Продовжимо знайомство з мікроконтролерами Cypress, а нині це Infineon, та засобом розробки ModusToolBoxIDE. В цій статті пропоную розібратись, як працювати з аналоговими блоками, такими як ADC та LPCOMP. Програмувати будемо в засобі розробки MTB_IDE, та драйверами PDL. В попередній статті "Встановлення ModusToolBox та перший проект на CY8CKIT-149 PSoC® 4100S Plus Prototyping Kit" розглянули як встановити MTB_IDE, та створили перший проект. Використовувати будемо все той же ж  KIT Prototyping CY8CKIT-149 PSoC4, але все що буде в цій статті, буде підходити до всіх девайсів які підтримуються MTB та драйверами PDL.

Створення проекту

Запускаємо ModuToolBoxIDE, та створюємо новий проект як на малюнку, на швидкій панелі тиснемо 1:

Створення нового проекту

Далі потрібно обрати мікроконтролер або плату розробника, в цьому випадку це KIT Prototyping CY8CKIT-149 PSoC4, у вас це може бути інший чип. Головне, щоб він підтримувався та мав на борту ADC та LPCOMP:

Вибір цілі

  1. Обираємо серію МК - PSoC4
  2. Обираємо плату з цієї серії
  3. Можна переглянути документацію по цій платі
  4. Тиснемо "Next"
Створювач проектів "Project Creator" запропонує обрати шаблон проекту з прикладом до якоїсь периферії, або пустий проект. Обираємо пустий. Нам потрібно з нуля розібратись зі всіма налаштуваннями і ньюансами.
Обираємо шаблон для проекту
  1. Обираєом шаблон пустого проекту
  2. Називаємо свій проект за смаком і своїми вподобаннями
Після того, як проект створено і він з'явився в "Project explorer", пропоную розгорнути дерево проекту і відкрити головний файл "main.c":
Відкриваємо файл main.c
Залишилось всього трішки - дописати демо-код. Чим і займемось. Але перед тим відкриємо зі швидкої панелі "device-configurator", та налаштуємо периферію, як слід, для наших потреб.
Панель швидкого доступу
  1. Побудувати проект
  2. Очистити проект
  3. Прошити МК і перейти в режим відладки
  4. Залити прошивку і запустити її
  5. Відкрити утіліту "Library Manager" 
  6. Відкрити утіліту "Device Configurator"
Саме зараз нас цікавить "Device Configurator". Запусимо його і оберемо ADC:
Обираємо ADC
  1. Периферія
  2. Аналогова периферія
  3. Програмований аналог PASS
  4. 12-bit SAR ADC
Далі перейдемо до налаштувань самого ADC:
Налаштування ADC частина 1

Налаштування ADC частина 2
  1. Оберемо опірну напругу для порівняння, таку як 3.3 Вольта
  2. Поки обиремо 2 канали, далі можливо додамо ще каналів
  3. Джерело тактування оберемо один з вільних дільників
  4. Назначемо вільний та доступний пін для 0 канала
  5. Назначемо вільний та доступний пін для 1 канала
Тиснемо "CTRL + S" та зберігаємо файл налаштувань. Ще можна переглянути що за код згенерувався для налаштування ADC і двох каналів:
Попередній перегляд коду налаштувань
  1. Перейдемо до вкладки "Code Preview"
  2. Переглянемо, сам код, який генерується в проект
Зберемо такий макет для дослідження, та напишемо демо-код:
Схема макету для дослідження ADC

Демо-код ADC

Перед тим як писати демо-код, додамо бібліотеку retarget до проекту за допомоги "Library manager", для того щоб друкувати повідомлення серіал термінал по UART:

Додаємо бібліотеку retarget
  1. Тиснемо вкладку "бібліотека"
  2. Обираємо периферію
  3. Та позначаємо необхідну бібліотеку
  4. Оновлюємо перелік бібліотек для проекту
В початковий код додаємо бібліотеку ""cy_retarget_io.h"":
#include "cy_pdl.h"
#include "cybsp.h"
#include "cy_retarget_io.h"
В головну функцію main додаємо ініціалізацію бібліотеки retarget для друку повідомлень в термінал:
result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);

if (result != CY_RSLT_SUCCESS)
{
	CY_ASSERT(0);
}
І на загал, код в файлі main.c буде виглядати таким чином:
#include "cy_pdl.h"
#include "cybsp.h"
#include "cy_retarget_io.h"

int main(void)
{
    cy_rslt_t result;
    uint16_t resADC[2];

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;

    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);

    if (result != CY_RSLT_SUCCESS)
    {
		CY_ASSERT(0);
    }

    /* Enable global interrupts */
    __enable_irq();

    printf("\x1b[2J\x1b[;H");
    printf("*------------------------------*\r\n");
    printf("* Demo ADC and LPCOMP started! *\r\n");
    printf("*------------------------------*\r\n");

    result = Cy_SAR_Init(SAR0, &pass_0_sar_0_config);

    if (result != CY_RSLT_SUCCESS)
    {
	CY_ASSERT(0);
    }

    Cy_SAR_Enable(SAR0);

    for (;;)
    {
    	Cy_SAR_StartConvert(SAR0, CY_SAR_START_CONVERT_SINGLE_SHOT);
    	Cy_SAR_IsEndConversion(SAR0, CY_SAR_WAIT_FOR_RESULT);
    	resADC[0] = Cy_SAR_GetResult16(SAR0, 0);
    	resADC[1] = Cy_SAR_GetResult16(SAR0, 1);
    	printf("ADC Result Channel 0 = %d mV   \r\n", Cy_SAR_CountsTo_mVolts(SAR0, 0, resADC[0]));
    	printf("ADC Result Channel 1 = %d mV   \r\n", Cy_SAR_CountsTo_mVolts(SAR0, 1, resADC[1]));
    	printf("\x1b[1F");
    	printf("\x1b[1F");
    	Cy_SysLib_Delay(1000);
    }
}
Заливаємо, запускаємо, відкриваємо термінал і спостерігаємо щось подібне:
Результат
Крутимо потенциометри і спостерігаємо за результатом.

Відео посібник


Вмикаємо і налаштовуємо LPCOMP

LPCOMP (Low Power Comparator) - компаратор з низьким споживанням. Відкриємо знову "device configurator" та увімкнемо і налаштуємо один з компараторів:
Вмикаємо LPCOMP
Та налаштовуємо як на цьому скріншоті:
Налаштування LPCOMP

  1. Конфігуруємо вихід компаратора як "Direct" коли напруга на позитивному вході менша за ту, що на негативному вході, то на виході 0, і навпаки, коли на позитивному вході напруга перевищила поріг, що є на негативному вході, то на виході буде 1. 
  2. Живлення і швидкість порівняння обираємо "Normal power/Fast".
  3. Виникає переривання в обох випадках, як по фронту, так і по спаду.
  4. Обираємо шпильку для позитивного входу.
  5. Обираємо шпильку для негативного входу.
  6. Обираємо шпильку для виходу.
  7. Обиремо, саме той пін для виходу, де є під'єднаний світлодіод, щоб наочно бачити результат порівняння вхідних напруг. Так як світлодіод під'єднаний постійно до 3.3В, то світитиме, коли на виході буде 0, а як на виході компаратора з'явиться 1 то світлодіод згасне.
Вибір шпильки для виходу компаратора

Зберігаємо зміни "CTRL+S" додаємо з'єднання компаратора і дільників.

Схема під'єднання

Додамо дротів з дільників на вхід компаратора

Демо-код для компаратора

#include "cy_pdl.h"
#include "cybsp.h"
#include "cy_retarget_io.h"
#include "stdbool.h"

volatile bool flagLPComp = false;
cy_stc_lpcomp_context_t lpcomp_0_context;

static void lpcomp_interrupt_handler(void);

int main(void)
{
    cy_rslt_t result;
    uint16_t resADC[2];


    cy_stc_sysint_t lpcomp_interrupt_config = {
    	.intrSrc = lpcomp_0_comp_0_IRQ,
	.intrPriority = 3
    };

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;

    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }

    result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);

    if (result != CY_RSLT_SUCCESS)
    {
	CY_ASSERT(0);
    }

    /* Enable global interrupts */
    __enable_irq();

    printf("\x1b[2J\x1b[;H");
    printf("*------------------------------*\r\n");
    printf("* Demo ADC and LPCOMP started! *\r\n");
    printf("*------------------------------*\r\n");

    result = Cy_SAR_Init(SAR0, &pass_0_sar_0_config);

    if (result != CY_RSLT_SUCCESS)
    {
	CY_ASSERT(0);
    }

    Cy_SAR_Enable(SAR0);

    Cy_LPComp_Init(LPCOMP, CY_LPCOMP_CHANNEL_0, &lpcomp_0_comp_0_config, &lpcomp_0_context);
    Cy_LPComp_Enable(LPCOMP, CY_LPCOMP_CHANNEL_0, &lpcomp_0_context);

    Cy_LPComp_SetInterruptMask(LPCOMP, CY_LPCOMP_CHANNEL0_INTR);
    Cy_SysInt_Init(&lpcomp_interrupt_config, &lpcomp_interrupt_handler);
    NVIC_ClearPendingIRQ(lpcomp_interrupt_config.intrSrc);
    NVIC_EnableIRQ(lpcomp_interrupt_config.intrSrc);

    for (;;)
    {
    	Cy_SAR_StartConvert(SAR0, CY_SAR_START_CONVERT_SINGLE_SHOT);
	Cy_SAR_IsEndConversion(SAR0, CY_SAR_WAIT_FOR_RESULT);
	resADC[0] = Cy_SAR_GetResult16(SAR0, 0);
	resADC[1] = Cy_SAR_GetResult16(SAR0, 1);
	printf("ADC Result Channel 0 (-input) = %d mV   \r\n", Cy_SAR_CountsTo_mVolts(SAR0, 0, resADC[0]));
	printf("ADC Result Channel 1 (+input) = %d mV   \r\n", Cy_SAR_CountsTo_mVolts(SAR0, 1, resADC[1]));
	if(flagLPComp)
	{
	    printf("Output PIN LPComp is HIGT\r\n");
	}
	else
	{
	    printf("Output PIN LPComp is LOW \r\n");
	}
	printf("\x1b[1F");
	printf("\x1b[1F");
	printf("\x1b[1F");
	Cy_SysLib_Delay(1000);
    }
}

static void lpcomp_interrupt_handler(void)
{
	if(CY_LPCOMP_CHANNEL0_INTR == Cy_LPComp_GetInterruptStatusMasked(LPCOMP))
	{
	    if(Cy_LPComp_GetCompare(LPCOMP, CY_LPCOMP_CHANNEL_0))
	    {
		flagLPComp = true;
	    }
	    else
	    {
		flagLPComp = false;
	    }
	    Cy_LPComp_ClearInterrupt(LPCOMP, CY_LPCOMP_CHANNEL0_INTR);
	    NVIC_ClearPendingIRQ(lpcomp_interrupt_IRQn);
	}
}
Крутимо потенциометром на позитивному вході компаратора, і спотерігаємо, що як напруга на позитивному вході перевищує напругу на негативному вході, то вихід компаратора встановлює високий рівень і навпаки.
Результат роботи

Відео посібник