Compare commits
13
Commits
f6e10a293a
..
v1.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0940814522 | ||
|
|
0d5f8f9c5f | ||
|
|
47c55515bb | ||
|
|
c1bd2c7e11 | ||
|
|
22b1f26aed | ||
|
|
d479a8d361 | ||
|
|
3a1a095e97 | ||
|
|
cbf724db2a | ||
|
|
dcd4ef7e1b | ||
|
|
02dee65b2b | ||
|
|
fb59015fca | ||
|
|
83c0ba3e74 | ||
|
|
e92aea0c84 |
No files matched your search
@@ -99,17 +99,20 @@ jobs:
|
||||
docker run --rm --network host -v trivy-cache:/root/.cache/ -e DOCKER_HOST=tcp://127.0.0.1:2375 aquasec/trivy:0.70.0 \
|
||||
image --severity HIGH,CRITICAL --exit-code 1 espdocs:ci
|
||||
|
||||
# Rotas por idioma, redirects e regras do livro (scripts/smoke-imagem.sh).
|
||||
# Um curl só na raiz não basta: ela redireciona, e uma página interna
|
||||
# quebrada ainda passaria.
|
||||
- name: A imagem sobe e responde
|
||||
if: ${{ steps.plano.outputs.reuse != 'true' }}
|
||||
run: |
|
||||
docker run -d --name espdocs-ci --network host -e PORT=3999 espdocs:ci
|
||||
for i in $(seq 1 30); do
|
||||
curl -fsS http://127.0.0.1:3999/ >/dev/null && ok=1 && break
|
||||
sleep 2
|
||||
done
|
||||
docker logs espdocs-ci | tail -5
|
||||
status=0
|
||||
scripts/smoke-imagem.sh http://127.0.0.1:3999 || status=1
|
||||
docker logs espdocs-ci | tail -15
|
||||
# O Next registra falhas de render no log mesmo quando responde.
|
||||
if docker logs espdocs-ci 2>&1 | grep -q '⨯'; then echo "O servidor registrou erro de render"; status=1; fi
|
||||
docker rm -f espdocs-ci >/dev/null
|
||||
test "${ok:-0}" = 1
|
||||
exit "$status"
|
||||
|
||||
# Passou em tudo: publica a mesma imagem que foi testada, sem reconstruir.
|
||||
- name: Publica inputs-<hash>
|
||||
|
||||
+78
-1
@@ -6,6 +6,80 @@ Tudo o que muda de relevante no ESPDocs está aqui. O formato segue o
|
||||
|
||||
## [Não lançado]
|
||||
|
||||
## [1.3.0] - 2026-11-01
|
||||
|
||||
### Adicionado
|
||||
|
||||
- Internacionalização completa para o idioma inglês (`en`) (Fase 3):
|
||||
- Ativação do inglês em `ENABLED_LOCALES = ["pt", "en"]` com reexibição do seletor de idiomas no cabeçalho.
|
||||
- Tradução técnica integral e paridade estrutural em `messages/en.json` (15 namespaces) e arquivos de dados em `data/en/` (`series.json`, `frameworks.json`, `conexoes/*.json`) e `lib/data/en/` (`glossario.js`, `diagnostico.js`, `componentes.js`, `topicos.js`).
|
||||
- 14 exemplos práticos de código com comentários em inglês em `public/exemplos/en/`.
|
||||
- Roteamento com slugs canônicos em inglês (`/en/catalog`, `/en/compare`, `/en/components`, `/en/diagnostics`, `/en/frameworks`, `/en/glossary`, `/en/selector`, `/en/about`).
|
||||
- Índice de busca dedicado por idioma em `/api/busca/[locale]`, com links direcionando aos slugs do idioma correspondente e caixa de busca localizada.
|
||||
- Exclusão total e estrita de referências ao livro no idioma inglês (menu, rodapé, busca, sitemap e metadados), mantendo `/en/livro` respondendo HTTP 404.
|
||||
- Tabela de catálogo com cabeçalhos traduzidos e mapeamento de valores na interface inglesa.
|
||||
- Negociação de idioma na raiz com fallback padrão para `en` para navegadores com idiomas inativos ou genéricos, e redirecionamento 307 de prefixos inativos (`es`, `fr`, `de`, `zh-CN`) para `/en` preservando o mapeamento de slugs.
|
||||
- Metadados de SEO, Open Graph e Twitter Cards localizados, com `hreflang` cruzado entre `pt-BR`, `en` e `x-default`.
|
||||
- Verificações permanentes contra vazamento de português no inglês: `scripts/check-i18n.mjs` falha em textos idênticos entre `pt` e `en` (fora de uma lista de termos técnicos), e `scripts/verifica-vazamentos.py`, chamado pelo teste de fumaça da CI, varre as 36 rotas em inglês, texto visível e JSON-LD.
|
||||
|
||||
### Alterado
|
||||
|
||||
- A raiz `/` passa a levar quem não fala português ao inglês (`/en`); o português continua em `/pt`. Idiomas ainda sem tradução (`es`, `fr`, `de`, `zh-CN`) redirecionam para `/en`.
|
||||
|
||||
## [1.2.0] - 2026-11-01
|
||||
|
||||
### Adicionado
|
||||
|
||||
- Infraestrutura de internacionalização com `next-intl` (Fase 1):
|
||||
- Roteamento com prefixo de idioma sob `app/[locale]/`, com 6 locales declarados (`pt`, `en`, `es`, `fr`, `de`, `zh-CN`).
|
||||
- `middleware.js` com negociação de idioma na raiz por cookie `NEXT_LOCALE` e cabeçalho `Accept-Language` (com pesos `q`), redirecionamento 308 de URLs antigas sem prefixo para `/pt/`, e retorno 404 para `/livro` fora do português.
|
||||
- Seletor de idiomas acessível no cabeçalho com atalho para os 6 idiomas, persistência via cookie `NEXT_LOCALE` e mapeamento de rota correspondente.
|
||||
- Regras de tipografia de sistema CJK para `zh-CN` e hifenização/quebra de palavras para `de` e `fr`.
|
||||
- Extração de strings e dados canônicos (Fase 2):
|
||||
- Catálogo de mensagens canônico `messages/pt.json` cobrindo 15 namespaces de páginas e componentes sem alteração de conteúdo.
|
||||
- Conjunto de dados canônicos em `data/pt/` (`series.json`, `frameworks.json`, `conexoes/*.json`) e módulos em `lib/data/pt/` (`glossario.js`, `diagnostico.js`, `componentes.js`, `topicos.js`) com carregadores por locale em `lib/data/index.js`.
|
||||
- Script automatizado de validação `check:i18n` integrado ao `npm run check`, verificando paridade de chaves, ausência de valores vazios e garantia estrita de ausência de referências ao livro fora do português.
|
||||
- Controle de idiomas ativos e proteção contra conteúdo não traduzido:
|
||||
- Configuração centralizada em `i18n/links.js` (`ENABLED_LOCALES`), atualmente restrita a `["pt"]`.
|
||||
- Redirecionamento 307 de qualquer prefixo de idioma inativo para `/pt` preservando o caminho ou mapeamento equivalente.
|
||||
- Negociação de idioma na raiz selecionando unicamente entre os idiomas ativos (com fallback em `pt`).
|
||||
- Seletor de idiomas no cabeçalho oculto enquanto apenas um idioma estiver ativo.
|
||||
- Sitemap, hreflang/alternates e build SSG restritos aos idiomas ativos.
|
||||
|
||||
### Alterado
|
||||
|
||||
- Todas as páginas passam a viver sob `/pt/` (por exemplo `/pt/series`). As URLs
|
||||
antigas, sem prefixo, redirecionam com 308 para o endereço novo, e a raiz `/`
|
||||
redireciona para o idioma negociado. O conteúdo do site em português não mudou.
|
||||
- O teste de subida da imagem na CI virou `scripts/smoke-imagem.sh`: confere as
|
||||
rotas de cada idioma, a negociação de `Accept-Language`, os redirects 308 das
|
||||
URLs antigas, o 404 do livro fora do português e a metadata no `<head>`, e
|
||||
falha se o servidor registrar erro de render. O `curl` só na raiz deixou passar
|
||||
uma home quebrada.
|
||||
- A metadata (título, `canonical`, Open Graph) sempre sai no `<head>` do HTML
|
||||
inicial, para qualquer cliente, como já era antes do i18n.
|
||||
- A raiz `/` redireciona direto para `/<idioma>`, em um salto só.
|
||||
|
||||
## [1.1.0] - 2026-11-01
|
||||
|
||||
### Adicionado
|
||||
|
||||
- Busca no site, aberta pelo botão do cabeçalho ou por Ctrl/⌘+K. O índice
|
||||
(séries, frameworks, glossário, erros de diagnóstico, componentes e conexões)
|
||||
é gerado no build, em `/api/busca`.
|
||||
|
||||
### Alterado
|
||||
|
||||
- Os links do repositório do projeto (rodapé, "Sobre", dados estruturados)
|
||||
apontam para o Gitea, e o ícone do GitHub virou o do Gitea. Os links dos
|
||||
frameworks da Espressif continuam no GitHub, porque os repositórios são deles.
|
||||
- O site passou a rodar na Oracle, a partir da imagem Docker do registro do
|
||||
Gitea, em `espdocs.cienciaembarcada.com.br` e `espdocs.lucasrguerra.dev.br`.
|
||||
- CI: a imagem é construída, escaneada e testada uma vez, em arm64, no push da
|
||||
branch, e o release só aplica as tags; o gatilho `pull_request` (que repetia o
|
||||
push) e o segundo `next build` do job de lint saíram, e os caches do npm e da
|
||||
compilação do Next ficam entre as execuções.
|
||||
|
||||
## [1.0.0] - 2026-10-30
|
||||
|
||||
A primeira versão com tag. O trabalho anterior nunca foi tagueado, então esta
|
||||
@@ -60,5 +134,8 @@ entrada resume tudo desde o primeiro commit, em 2025-10-21, até a imagem Docker
|
||||
otimização de imagens (GHSA-2464-fhr4-w9xw), e `postcss` fixado acima da cópia
|
||||
embutida no `next`.
|
||||
|
||||
[Não lançado]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/compare/v1.0.0...HEAD
|
||||
[Não lançado]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/compare/v1.3.0...HEAD
|
||||
[1.3.0]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/compare/v1.2.0...v1.3.0
|
||||
[1.2.0]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/compare/v1.1.0...v1.2.0
|
||||
[1.1.0]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/compare/v1.0.0...v1.1.0
|
||||
[1.0.0]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/releases/tag/v1.0.0
|
||||
@@ -0,0 +1,54 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
return paginaMeta({
|
||||
titulo: isEn ? "ESP32 Board Catalog" : "Catálogo de placas ESP32",
|
||||
descricao: isEn
|
||||
? "ESP32 development boards and DevKits available in Brazil, with filters by series, connector, and USB-serial converter."
|
||||
: "Placas de desenvolvimento com ESP32 disponíveis no Brasil, com filtro por série, conector e conversor USB-serial.",
|
||||
caminho: "/catalogo",
|
||||
locale,
|
||||
keywords: isEn
|
||||
? ["ESP32 boards", "ESP32 DevKit", "buy ESP32", "ESP32 DevKitC"]
|
||||
: ["placas ESP32", "DevKit ESP32", "comprar ESP32", "ESP32 DevKitC"],
|
||||
});
|
||||
}
|
||||
|
||||
export default async function Layout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.aplicacaoWeb({
|
||||
nome: isEn ? "ESP32 Development Board Catalog" : "Catálogo de Placas ESP32",
|
||||
descricao: isEn
|
||||
? "Interactive guide and catalog of development boards and DevKits featuring ESP32 microcontrollers."
|
||||
: "Guia e catálogo interativo de placas de desenvolvimento e DevKits com microcontroladores ESP32.",
|
||||
caminho: isEn ? "/en/catalog" : "/catalogo",
|
||||
locale,
|
||||
})
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: isEn ? "Home" : "Início", caminho: isEn ? "/en" : "/" },
|
||||
{ nome: isEn ? "Board Catalog" : "Catálogo de Placas", caminho: isEn ? "/en/catalog" : "/catalogo" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,29 +1,57 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useState, useEffect } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import BoardCard from "@/components/BoardCard";
|
||||
import { AlertTriangle, RefreshCw, Search, ShoppingCart, SlidersHorizontal } from "lucide-react";
|
||||
|
||||
const HEADER_MAP_EN = {
|
||||
"Nome": "Name",
|
||||
"Descrição": "Description",
|
||||
"Série": "Series",
|
||||
"Loja Oficial": "Official Store",
|
||||
"Fabricante": "Manufacturer",
|
||||
"Processador": "Processor",
|
||||
"Memória Flash": "Flash Memory",
|
||||
"PSRAM": "PSRAM",
|
||||
"Conector USB": "USB Connector",
|
||||
"Interface USB": "USB Interface",
|
||||
"Antena": "Antenna",
|
||||
"Bateria": "Battery",
|
||||
"Display": "Display",
|
||||
"Sensores": "Sensors",
|
||||
"Botões": "Buttons",
|
||||
"LEDs": "LEDs",
|
||||
};
|
||||
|
||||
const VALUE_MAP_EN = {
|
||||
"Sim": "Yes",
|
||||
"Não": "No",
|
||||
"Opcional": "Optional",
|
||||
};
|
||||
|
||||
export default function PlacasPage() {
|
||||
const pathname = usePathname() || "";
|
||||
const isEn = pathname === "/en" || pathname.startsWith("/en/");
|
||||
|
||||
const [boards, setBoards] = useState([]);
|
||||
const [filteredBoards, setFilteredBoards] = useState([]);
|
||||
const [headers, setHeaders] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [activeFilters, setActiveFilters] = useState({});
|
||||
const [filterOptions, setFilterOptions] = useState({});
|
||||
const [filtrosAbertos, setFiltrosAbertos] = useState(false);
|
||||
|
||||
const excludedColumns = ['Nome', 'Descrição', 'Link', 'Imagem', 'Loja Oficial'];
|
||||
const excludedColumns = ["Nome", "Descrição", "Link", "Imagem", "Loja Oficial"];
|
||||
|
||||
useEffect(() => {
|
||||
fetchBoards();
|
||||
// No desktop os filtros ficam sempre à vista; no celular começam recolhidos.
|
||||
setFiltrosAbertos(window.matchMedia('(min-width: 1024px)').matches);
|
||||
setFiltrosAbertos(window.matchMedia("(min-width: 1024px)").matches);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -33,17 +61,17 @@ export default function PlacasPage() {
|
||||
const fetchBoards = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await fetch('/api/placas');
|
||||
|
||||
const response = await fetch("/api/placas");
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Erro ao carregar dados das placas');
|
||||
throw new Error(isEn ? "Failed to load board data" : "Erro ao carregar dados das placas");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
setBoards(result.data);
|
||||
setHeaders(result.headers);
|
||||
setFilteredBoards(result.data);
|
||||
|
||||
|
||||
generateFilterOptions(result.data, result.headers);
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
@@ -54,26 +82,24 @@ export default function PlacasPage() {
|
||||
|
||||
const generateFilterOptions = (data, headers) => {
|
||||
const options = {};
|
||||
const filterableColumns = headers.filter(h => !excludedColumns.includes(h));
|
||||
const filterableColumns = headers.filter((h) => !excludedColumns.includes(h));
|
||||
|
||||
filterableColumns.forEach(column => {
|
||||
filterableColumns.forEach((column) => {
|
||||
const uniqueValues = new Set();
|
||||
data.forEach(item => {
|
||||
data.forEach((item) => {
|
||||
const value = item[column];
|
||||
if (value && value.toString().trim()) {
|
||||
uniqueValues.add(value.toString().trim());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const values = Array.from(uniqueValues).sort();
|
||||
|
||||
// Verificar se é um filtro binário (apenas Sim/Não/Opcional)
|
||||
const binaryValues = ['Sim', 'Não', 'Opcional'];
|
||||
const isBinaryFilter = values.every(v => binaryValues.includes(v));
|
||||
|
||||
const binaryValues = ["Sim", "Não", "Opcional"];
|
||||
const isBinaryFilter = values.every((v) => binaryValues.includes(v));
|
||||
|
||||
options[column] = {
|
||||
values: values,
|
||||
isBinary: isBinaryFilter
|
||||
isBinary: isBinaryFilter,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -84,7 +110,7 @@ export default function PlacasPage() {
|
||||
let filtered = [...boards];
|
||||
|
||||
if (searchTerm) {
|
||||
filtered = filtered.filter(board => {
|
||||
filtered = filtered.filter((board) => {
|
||||
const searchLower = searchTerm.toLowerCase();
|
||||
return (
|
||||
board.Nome?.toLowerCase().includes(searchLower) ||
|
||||
@@ -93,16 +119,13 @@ export default function PlacasPage() {
|
||||
});
|
||||
}
|
||||
|
||||
Object.keys(activeFilters).forEach(column => {
|
||||
Object.keys(activeFilters).forEach((column) => {
|
||||
if (activeFilters[column] && activeFilters[column].length > 0) {
|
||||
filtered = filtered.filter(board => {
|
||||
filtered = filtered.filter((board) => {
|
||||
const boardValue = board[column]?.toString().trim();
|
||||
|
||||
// Para filtros binários, o valor armazenado é 'binary-enabled'
|
||||
if (activeFilters[column].includes('binary-enabled')) {
|
||||
return boardValue === 'Sim' || boardValue === 'Opcional';
|
||||
if (activeFilters[column].includes("binary-enabled")) {
|
||||
return boardValue === "Sim" || boardValue === "Opcional";
|
||||
}
|
||||
|
||||
return activeFilters[column].includes(boardValue);
|
||||
});
|
||||
}
|
||||
@@ -112,21 +135,19 @@ export default function PlacasPage() {
|
||||
};
|
||||
|
||||
const handleFilterToggle = (column, value) => {
|
||||
setActiveFilters(prev => {
|
||||
setActiveFilters((prev) => {
|
||||
const newFilters = { ...prev };
|
||||
|
||||
|
||||
if (!newFilters[column]) {
|
||||
newFilters[column] = [value];
|
||||
} else {
|
||||
const index = newFilters[column].indexOf(value);
|
||||
if (index > -1) {
|
||||
// Remove o valor
|
||||
newFilters[column] = newFilters[column].filter(v => v !== value);
|
||||
newFilters[column] = newFilters[column].filter((v) => v !== value);
|
||||
if (newFilters[column].length === 0) {
|
||||
delete newFilters[column];
|
||||
}
|
||||
} else {
|
||||
// Adiciona o valor
|
||||
newFilters[column] = [...newFilters[column], value];
|
||||
}
|
||||
}
|
||||
@@ -137,7 +158,7 @@ export default function PlacasPage() {
|
||||
|
||||
const clearFilters = () => {
|
||||
setActiveFilters({});
|
||||
setSearchTerm('');
|
||||
setSearchTerm("");
|
||||
};
|
||||
|
||||
const activeFilterCount = Object.keys(activeFilters).length + (searchTerm ? 1 : 0);
|
||||
@@ -146,11 +167,16 @@ export default function PlacasPage() {
|
||||
|
||||
const hero = (
|
||||
<PageHero
|
||||
trail={[{ label: "Catálogo de placas" }]}
|
||||
isEn={isEn}
|
||||
trail={[{ label: isEn ? "Board Catalog" : "Catálogo de placas" }]}
|
||||
icon={ShoppingCart}
|
||||
label="DevKits e módulos reais"
|
||||
title="Catálogo de placas ESP32"
|
||||
lede="Compare placas oficiais e alternativas para o seu projeto: interface USB, sensores integrados e link direto para a loja."
|
||||
label={isEn ? "Real DevKits and modules" : "DevKits e módulos reais"}
|
||||
title={isEn ? "ESP32 Board Catalog" : "Catálogo de placas ESP32"}
|
||||
lede={
|
||||
isEn
|
||||
? "Compare official and third-party boards for your project: USB interface, on-board sensors and direct store links."
|
||||
: "Compare placas oficiais e alternativas para o seu projeto: interface USB, sensores integrados e link direto para a loja."
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -160,13 +186,15 @@ export default function PlacasPage() {
|
||||
<Header />
|
||||
<main id="conteudo">
|
||||
{hero}
|
||||
<section className="shell section pt-10" aria-busy="true" aria-label="Carregando placas">
|
||||
<section className="shell section pt-10" aria-busy="true" aria-label={isEn ? "Loading boards" : "Carregando placas"}>
|
||||
<div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
|
||||
{Array.from({ length: 6 }).map((_, i) => (
|
||||
<div key={i} className="card h-72 animate-pulse bg-surface-2" />
|
||||
))}
|
||||
</div>
|
||||
<p role="status" className="mt-6 text-center text-sm text-muted">Consultando o banco de placas…</p>
|
||||
<p role="status" className="mt-6 text-center text-sm text-muted">
|
||||
{isEn ? "Querying boards database…" : "Consultando o banco de placas…"}
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
<Footer />
|
||||
@@ -184,11 +212,15 @@ export default function PlacasPage() {
|
||||
<div role="alert" className="callout callout-danger flex items-start gap-3">
|
||||
<AlertTriangle className="mt-0.5 h-5 w-5 shrink-0 text-danger" aria-hidden="true" />
|
||||
<div>
|
||||
<p className="font-semibold text-ink">Não foi possível carregar as placas</p>
|
||||
<p className="mt-1">{error}. Verifique a conexão e tente de novo.</p>
|
||||
<p className="font-semibold text-ink">
|
||||
{isEn ? "Could not load boards" : "Não foi possível carregar as placas"}
|
||||
</p>
|
||||
<p className="mt-1">
|
||||
{error}. {isEn ? "Check your connection and try again." : "Verifique a conexão e tente de novo."}
|
||||
</p>
|
||||
<button type="button" onClick={fetchBoards} className="btn btn-primary btn-sm mt-4">
|
||||
<RefreshCw className="h-4 w-4" aria-hidden="true" />
|
||||
Tentar novamente
|
||||
{isEn ? "Try again" : "Tentar novamente"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -203,14 +235,14 @@ export default function PlacasPage() {
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<label htmlFor="busca-placa" className="text-sm font-semibold text-ink">
|
||||
Buscar placa
|
||||
{isEn ? "Search board" : "Buscar placa"}
|
||||
</label>
|
||||
<div className="relative mt-2">
|
||||
<Search className="pointer-events-none absolute left-3.5 top-1/2 h-4 w-4 -translate-y-1/2 text-muted" aria-hidden="true" />
|
||||
<input
|
||||
id="busca-placa"
|
||||
type="search"
|
||||
placeholder="Nome ou descrição"
|
||||
placeholder={isEn ? "Name or description" : "Nome ou descrição"}
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="field pl-10 text-sm"
|
||||
@@ -221,11 +253,12 @@ export default function PlacasPage() {
|
||||
{filterableColumns.map((column) => {
|
||||
const filterData = filterOptions[column];
|
||||
if (!filterData) return null;
|
||||
const colLabel = isEn ? (HEADER_MAP_EN[column] || column) : column;
|
||||
|
||||
if (filterData.isBinary) {
|
||||
return (
|
||||
<label key={column} className="flex min-h-11 cursor-pointer items-center justify-between gap-3 border-t border-line pt-4 text-sm font-medium text-ink-soft">
|
||||
{column}
|
||||
{colLabel}
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={activeFilters[column]?.includes("binary-enabled") || false}
|
||||
@@ -239,21 +272,24 @@ export default function PlacasPage() {
|
||||
return (
|
||||
<fieldset key={column} className="border-t border-line pt-4">
|
||||
<legend className="flex items-center gap-2 pr-2 text-sm font-semibold text-ink">
|
||||
{column}
|
||||
{colLabel}
|
||||
{activeFilters[column]?.length > 0 && <span className="chip chip-accent px-2 py-0">{activeFilters[column].length}</span>}
|
||||
</legend>
|
||||
<div className="mt-2 max-h-44 space-y-0.5 overflow-y-auto pr-1">
|
||||
{filterData.values.map((option) => (
|
||||
<label key={option} className="flex min-h-10 cursor-pointer items-center gap-3 rounded-lg px-2 text-sm text-muted transition-colors hover:bg-surface-2 hover:text-ink">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={activeFilters[column]?.includes(option) || false}
|
||||
onChange={() => handleFilterToggle(column, option)}
|
||||
className="h-4 w-4 shrink-0 cursor-pointer accent-[var(--accent)]"
|
||||
/>
|
||||
{option}
|
||||
</label>
|
||||
))}
|
||||
{filterData.values.map((option) => {
|
||||
const optLabel = isEn ? (VALUE_MAP_EN[option] || option) : option;
|
||||
return (
|
||||
<label key={option} className="flex min-h-10 cursor-pointer items-center gap-3 rounded-lg px-2 text-sm text-muted transition-colors hover:bg-surface-2 hover:text-ink">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={activeFilters[column]?.includes(option) || false}
|
||||
onChange={() => handleFilterToggle(column, option)}
|
||||
className="h-4 w-4 shrink-0 cursor-pointer accent-[var(--accent)]"
|
||||
/>
|
||||
{optLabel}
|
||||
</label>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</fieldset>
|
||||
);
|
||||
@@ -268,23 +304,26 @@ export default function PlacasPage() {
|
||||
<main id="conteudo">
|
||||
{hero}
|
||||
|
||||
<section className="shell section pt-10 sm:pt-12" aria-label="Placas">
|
||||
<section className="shell section pt-10 sm:pt-12" aria-label={isEn ? "Boards" : "Placas"}>
|
||||
<div className="grid gap-8 lg:grid-cols-[17rem_1fr] lg:gap-10">
|
||||
<aside className="lg:sticky lg:top-28 lg:self-start">
|
||||
<details className="panel" open={filtrosAbertos} onToggle={(e) => setFiltrosAbertos(e.currentTarget.open)}>
|
||||
<summary className="flex min-h-12 cursor-pointer list-none items-center justify-between gap-3 px-5 py-3 lg:cursor-default">
|
||||
<span className="flex items-center gap-2 text-sm font-semibold text-ink">
|
||||
<SlidersHorizontal className="h-4 w-4 text-accent" aria-hidden="true" />
|
||||
Filtros
|
||||
{isEn ? "Filters" : "Filtros"}
|
||||
{activeFilterCount > 0 && <span className="chip chip-accent px-2 py-0">{activeFilterCount}</span>}
|
||||
</span>
|
||||
{activeFilterCount > 0 && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => { e.preventDefault(); clearFilters(); }}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
clearFilters();
|
||||
}}
|
||||
className="text-sm font-medium text-accent hover:text-accent-strong"
|
||||
>
|
||||
Limpar
|
||||
{isEn ? "Clear" : "Limpar"}
|
||||
</button>
|
||||
)}
|
||||
</summary>
|
||||
@@ -295,16 +334,28 @@ export default function PlacasPage() {
|
||||
<div>
|
||||
<p role="status" aria-live="polite" className="text-sm text-muted">
|
||||
<strong className="font-semibold text-ink">{filteredBoards.length}</strong>{" "}
|
||||
{filteredBoards.length === 1 ? "placa encontrada" : "placas encontradas"}
|
||||
{isEn
|
||||
? filteredBoards.length === 1
|
||||
? "board found"
|
||||
: "boards found"
|
||||
: filteredBoards.length === 1
|
||||
? "placa encontrada"
|
||||
: "placas encontradas"}
|
||||
</p>
|
||||
|
||||
{filteredBoards.length === 0 ? (
|
||||
<div className="card mt-4 px-6 py-14 text-center">
|
||||
<Search className="mx-auto h-10 w-10 text-muted" aria-hidden="true" />
|
||||
<h2 className="mt-4 font-display text-xl font-semibold text-ink">Nenhuma placa com esses filtros</h2>
|
||||
<p className="mx-auto mt-2 max-w-md text-sm text-muted">Remova alguns filtros ou busque por outro nome.</p>
|
||||
<h2 className="mt-4 font-display text-xl font-semibold text-ink">
|
||||
{isEn ? "No boards match these filters" : "Nenhuma placa com esses filtros"}
|
||||
</h2>
|
||||
<p className="mx-auto mt-2 max-w-md text-sm text-muted">
|
||||
{isEn
|
||||
? "Remove some filters or search by another name."
|
||||
: "Remova alguns filtros ou busque por outro nome."}
|
||||
</p>
|
||||
<button type="button" onClick={clearFilters} className="btn btn-primary mt-6">
|
||||
Limpar filtros
|
||||
{isEn ? "Clear filters" : "Limpar filtros"}
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
@@ -0,0 +1,91 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
return paginaMeta({
|
||||
titulo: isEn ? "Compare ESP32 Series: Side-by-Side Table" : "Comparar séries ESP32",
|
||||
descricao: isEn
|
||||
? "Compare up to four ESP32 series side by side: processor, Wi-Fi, Bluetooth, memory, GPIO, peripherals, and hardware security, with official datasheet data."
|
||||
: "Compare até quatro séries de ESP32 lado a lado: processador, Wi-Fi, Bluetooth, memória, GPIO, periféricos e segurança em hardware, com os dados dos datasheets oficiais.",
|
||||
caminho: "/comparacao",
|
||||
locale,
|
||||
keywords: isEn
|
||||
? ["compare ESP32", "ESP32 vs ESP32-S3", "ESP32 comparison table", "which ESP32 is best"]
|
||||
: ["comparar ESP32", "ESP32 vs ESP32-S3", "tabela comparativa ESP32", "qual ESP32 é melhor"],
|
||||
});
|
||||
}
|
||||
|
||||
const faqsPt = [
|
||||
{
|
||||
pergunta: "Como comparar microcontroladores ESP32 lado a lado?",
|
||||
resposta: "O comparador do ESPDocs permite selecionar até quatro séries simultaneamente para confrontar arquitetura, frequência de clock, memória SRAM/PSRAM, padrões de rádio (Wi-Fi 4/6, Bluetooth 5/6, 802.15.4), interfaces de periféricos e blocos de segurança em hardware.",
|
||||
},
|
||||
{
|
||||
pergunta: "Qual a diferença entre o ESP32 clássico e o ESP32-S3?",
|
||||
resposta: "O ESP32 clássico usa núcleos Xtensa LX6 e Bluetooth clássico/LE. O ESP32-S3 traz núcleos Xtensa LX7 com instruções vetoriais para inteligência artificial (TinyML), USB nativo OTG, mais GPIOs (45 contra 36) e Bluetooth 5.0 LE.",
|
||||
},
|
||||
{
|
||||
pergunta: "Qual a diferença entre ESP32-C3 e ESP32-C6?",
|
||||
resposta: "O ESP32-C3 é um microcontrolador RISC-V com Wi-Fi 4 e Bluetooth 5 LE. O ESP32-C6 evolui para Wi-Fi 6 (802.11ax), Bluetooth 5.4 LE, rádio IEEE 802.15.4 para Zigbee 3.0 e Thread 1.3, além de coprocessador de ultrabaixo consumo.",
|
||||
},
|
||||
];
|
||||
|
||||
const faqsEn = [
|
||||
{
|
||||
pergunta: "How to compare ESP32 microcontrollers side by side?",
|
||||
resposta: "The ESPDocs comparator lets you select up to four series simultaneously to compare architecture, clock speed, SRAM/PSRAM memory, radio standards (Wi-Fi 4/6, Bluetooth 5/6, 802.15.4), peripheral interfaces, and hardware security blocks.",
|
||||
},
|
||||
{
|
||||
pergunta: "What is the difference between classic ESP32 and ESP32-S3?",
|
||||
resposta: "The classic ESP32 uses Xtensa LX6 cores and legacy Bluetooth/LE. The ESP32-S3 brings Xtensa LX7 cores with vector instructions for AI (TinyML), native USB OTG, more GPIOs (45 vs 36), and Bluetooth 5.0 LE.",
|
||||
},
|
||||
{
|
||||
pergunta: "What is the difference between ESP32-C3 and ESP32-C6?",
|
||||
resposta: "The ESP32-C3 is a RISC-V microcontroller with Wi-Fi 4 and Bluetooth 5 LE. The ESP32-C6 upgrades to Wi-Fi 6 (802.11ax), Bluetooth 5.4 LE, IEEE 802.15.4 radio for Zigbee 3.0 and Thread 1.3, plus an ultra-low-power coprocessor.",
|
||||
},
|
||||
];
|
||||
|
||||
export default async function Layout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const faqs = isEn ? faqsEn : faqsPt;
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.aplicacaoWeb({
|
||||
nome: isEn ? "ESP32 Series Comparator" : "Comparador de Séries ESP32",
|
||||
descricao: isEn
|
||||
? "Technical comparison table to analyze specifications, pinouts, and features of multiple ESP32 series."
|
||||
: "Tabela comparativa técnica para analisar especificações, pinagens e recursos de múltiplas séries de ESP32.",
|
||||
caminho: isEn ? "/en/compare" : "/comparacao",
|
||||
locale,
|
||||
})
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: isEn ? "Home" : "Início", caminho: isEn ? "/en" : "/" },
|
||||
{ nome: isEn ? "Compare Series" : "Comparar Séries", caminho: isEn ? "/en/compare" : "/comparacao" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.perguntas(faqs)),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,432 @@
|
||||
"use client";
|
||||
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import { useEffect, useState, useMemo, Fragment } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import seriesDataPt from "@/public/series.json";
|
||||
import seriesDataEn from "@/data/en/series.json";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
import { ArrowRight, ArrowUpRight, Check, ChevronDown, Scale } from "lucide-react";
|
||||
|
||||
const MIN_SERIES = 2;
|
||||
const MAX_SERIES = 4;
|
||||
|
||||
/* Lê "seguranca.ecc" além de chaves simples. */
|
||||
function valorDe(objeto, caminho) {
|
||||
return caminho.split(".").reduce((atual, parte) => atual?.[parte], objeto);
|
||||
}
|
||||
|
||||
const COMPARE_FIELDS_PT = [
|
||||
{ category: "Geral", fields: [
|
||||
{ key: "nome_completo", label: "Nome Completo" },
|
||||
{ key: "descricao", label: "Descrição" },
|
||||
]},
|
||||
{ category: "Disponibilidade e Ferramentas", fields: [
|
||||
{ key: "esp_idf_minimo", label: "ESP-IDF mínimo" },
|
||||
{ key: "arduino_core", label: "Core Arduino" },
|
||||
{ key: "depuracao", label: "Depuração / JTAG" },
|
||||
{ key: "encapsulamento", label: "Encapsulamento" },
|
||||
{ key: "modulos", label: "Módulos disponíveis" },
|
||||
]},
|
||||
{ category: "Processador", fields: [
|
||||
{ key: "arquitetura", label: "Arquitetura" },
|
||||
{ key: "nucleos", label: "Núcleos" },
|
||||
{ key: "frequencia", label: "Frequência" },
|
||||
{ key: "coprocessador_ulp", label: "Coprocessador ULP" },
|
||||
{ key: "aceleradores_ia", label: "Aceleradores de IA" },
|
||||
]},
|
||||
{ category: "Conectividade", fields: [
|
||||
{ key: "wifi", label: "Wi-Fi" },
|
||||
{ key: "bluetooth", label: "Bluetooth" },
|
||||
{ key: "zigbee_thread", label: "Zigbee/Thread" },
|
||||
{ key: "matter", label: "Matter" },
|
||||
{ key: "ethernet", label: "Ethernet" },
|
||||
]},
|
||||
{ category: "Memória", fields: [
|
||||
{ key: "memoria_sram", label: "SRAM" },
|
||||
{ key: "memoria_sram_rtc", label: "SRAM RTC" },
|
||||
{ key: "memoria_rom", label: "ROM" },
|
||||
{ key: "flash_externa", label: "Flash Externa" },
|
||||
{ key: "psram_externa", label: "PSRAM Externa" },
|
||||
]},
|
||||
{ category: "Periféricos Digitais", fields: [
|
||||
{ key: "gpio", label: "GPIO" },
|
||||
{ key: "uart", label: "UART" },
|
||||
{ key: "spi", label: "SPI" },
|
||||
{ key: "i2c", label: "I²C" },
|
||||
{ key: "i2s", label: "I²S" },
|
||||
{ key: "pwm", label: "PWM" },
|
||||
{ key: "can", label: "CAN" },
|
||||
{ key: "usb", label: "USB" },
|
||||
{ key: "depuracao", label: "Depuração / JTAG" },
|
||||
{ key: "sdio", label: "SDIO" },
|
||||
]},
|
||||
{ category: "Periféricos Analógicos", fields: [
|
||||
{ key: "adc", label: "ADC" },
|
||||
{ key: "dac", label: "DAC" },
|
||||
{ key: "touch", label: "Touch Capacitivo" },
|
||||
{ key: "sensor_hall", label: "Sensor Hall" },
|
||||
{ key: "sensor_temperatura", label: "Sensor de Temperatura" },
|
||||
]},
|
||||
{ category: "Segurança", fields: [
|
||||
{ key: "seguranca.aes", label: "AES" },
|
||||
{ key: "seguranca.sha", label: "SHA" },
|
||||
{ key: "seguranca.rsa", label: "RSA / MPI" },
|
||||
{ key: "seguranca.ecc", label: "ECC (curvas elípticas)" },
|
||||
{ key: "seguranca.ecdsa", label: "ECDSA em hardware" },
|
||||
{ key: "seguranca.hmac", label: "HMAC" },
|
||||
{ key: "seguranca.assinatura_digital", label: "Assinatura Digital (DS)" },
|
||||
{ key: "seguranca.key_manager", label: "Key Manager" },
|
||||
{ key: "seguranca.rng", label: "Gerador aleatório (RNG)" },
|
||||
{ key: "seguranca.criptografia_flash", label: "Criptografia de flash" },
|
||||
{ key: "seguranca.secure_boot", label: "Secure Boot" },
|
||||
{ key: "seguranca.protecao_dpa", label: "Proteção contra DPA" },
|
||||
]},
|
||||
{ category: "Interfaces Especiais", fields: [
|
||||
{ key: "lcd", label: "LCD" },
|
||||
{ key: "camera", label: "Câmera" },
|
||||
{ key: "mipi_csi", label: "MIPI CSI" },
|
||||
{ key: "mipi_dsi", label: "MIPI DSI" },
|
||||
{ key: "ethernet_mac", label: "Ethernet MAC" },
|
||||
]},
|
||||
{ category: "Especificações Ambientais", fields: [
|
||||
{ key: "temperatura_operacao", label: "Temp. Operação" },
|
||||
{ key: "temperatura_armazenamento", label: "Temp. Armazenamento" },
|
||||
]},
|
||||
];
|
||||
|
||||
const COMPARE_FIELDS_EN = [
|
||||
{ category: "General", fields: [
|
||||
{ key: "nome_completo", label: "Full Name" },
|
||||
{ key: "descricao", label: "Description" },
|
||||
]},
|
||||
{ category: "Availability and Tools", fields: [
|
||||
{ key: "esp_idf_minimo", label: "Minimum ESP-IDF" },
|
||||
{ key: "arduino_core", label: "Arduino Core" },
|
||||
{ key: "depuracao", label: "Debugging / JTAG" },
|
||||
{ key: "encapsulamento", label: "Package" },
|
||||
{ key: "modulos", label: "Available Modules" },
|
||||
]},
|
||||
{ category: "Processor", fields: [
|
||||
{ key: "arquitetura", label: "Architecture" },
|
||||
{ key: "nucleos", label: "Cores" },
|
||||
{ key: "frequencia", label: "Frequency" },
|
||||
{ key: "coprocessador_ulp", label: "ULP Coprocessor" },
|
||||
{ key: "aceleradores_ia", label: "AI Accelerators" },
|
||||
]},
|
||||
{ category: "Connectivity", fields: [
|
||||
{ key: "wifi", label: "Wi-Fi" },
|
||||
{ key: "bluetooth", label: "Bluetooth" },
|
||||
{ key: "zigbee_thread", label: "Zigbee/Thread" },
|
||||
{ key: "matter", label: "Matter" },
|
||||
{ key: "ethernet", label: "Ethernet" },
|
||||
]},
|
||||
{ category: "Memory", fields: [
|
||||
{ key: "memoria_sram", label: "SRAM" },
|
||||
{ key: "memoria_sram_rtc", label: "RTC SRAM" },
|
||||
{ key: "memoria_rom", label: "ROM" },
|
||||
{ key: "flash_externa", label: "External Flash" },
|
||||
{ key: "psram_externa", label: "External PSRAM" },
|
||||
]},
|
||||
{ category: "Digital Peripherals", fields: [
|
||||
{ key: "gpio", label: "GPIO" },
|
||||
{ key: "uart", label: "UART" },
|
||||
{ key: "spi", label: "SPI" },
|
||||
{ key: "i2c", label: "I²C" },
|
||||
{ key: "i2s", label: "I²S" },
|
||||
{ key: "pwm", label: "PWM" },
|
||||
{ key: "can", label: "CAN" },
|
||||
{ key: "usb", label: "USB" },
|
||||
{ key: "depuracao", label: "Debugging / JTAG" },
|
||||
{ key: "sdio", label: "SDIO" },
|
||||
]},
|
||||
{ category: "Analog Peripherals", fields: [
|
||||
{ key: "adc", label: "ADC" },
|
||||
{ key: "dac", label: "DAC" },
|
||||
{ key: "touch", label: "Capacitive Touch" },
|
||||
{ key: "sensor_hall", label: "Hall Sensor" },
|
||||
{ key: "sensor_temperatura", label: "Temperature Sensor" },
|
||||
]},
|
||||
{ category: "Security", fields: [
|
||||
{ key: "seguranca.aes", label: "AES" },
|
||||
{ key: "seguranca.sha", label: "SHA" },
|
||||
{ key: "seguranca.rsa", label: "RSA / MPI" },
|
||||
{ key: "seguranca.ecc", label: "ECC (elliptic curves)" },
|
||||
{ key: "seguranca.ecdsa", label: "Hardware ECDSA" },
|
||||
{ key: "seguranca.hmac", label: "HMAC" },
|
||||
{ key: "seguranca.assinatura_digital", label: "Digital Signature (DS)" },
|
||||
{ key: "seguranca.key_manager", label: "Key Manager" },
|
||||
{ key: "seguranca.rng", label: "Random Generator (TRNG)" },
|
||||
{ key: "seguranca.criptografia_flash", label: "Flash Encryption" },
|
||||
{ key: "seguranca.secure_boot", label: "Secure Boot" },
|
||||
{ key: "seguranca.protecao_dpa", label: "DPA Protection" },
|
||||
]},
|
||||
{ category: "Special Interfaces", fields: [
|
||||
{ key: "lcd", label: "LCD" },
|
||||
{ key: "camera", label: "Camera" },
|
||||
{ key: "mipi_csi", label: "MIPI CSI" },
|
||||
{ key: "mipi_dsi", label: "MIPI DSI" },
|
||||
{ key: "ethernet_mac", label: "Ethernet MAC" },
|
||||
]},
|
||||
{ category: "Environmental Specifications", fields: [
|
||||
{ key: "temperatura_operacao", label: "Operating Temp." },
|
||||
{ key: "temperatura_armazenamento", label: "Storage Temp." },
|
||||
]},
|
||||
];
|
||||
|
||||
export default function Comparacao() {
|
||||
const pathname = usePathname();
|
||||
const isEn = pathname?.startsWith("/en");
|
||||
const currentLocale = isEn ? "en" : "pt";
|
||||
const seriesData = isEn ? seriesDataEn : seriesDataPt;
|
||||
const compareFields = isEn ? COMPARE_FIELDS_EN : COMPARE_FIELDS_PT;
|
||||
|
||||
const [selectedSeries, setSelectedSeries] = useState(["ESP32", "ESP32-S3"]);
|
||||
const [soDiferencas, setSoDiferencas] = useState(false);
|
||||
const [collapsedCategories, setCollapsedCategories] = useState(() => ({
|
||||
[isEn ? "Special Interfaces" : "Interfaces Especiais"]: true,
|
||||
[isEn ? "Environmental Specifications" : "Especificações Ambientais"]: true,
|
||||
}));
|
||||
|
||||
const series = Object.entries(seriesData);
|
||||
|
||||
// O seletor envia as séries finalistas em ?chips=ESP32-S3,ESP32-C6.
|
||||
useEffect(() => {
|
||||
const chips = new URLSearchParams(window.location.search).get("chips");
|
||||
if (!chips) return;
|
||||
const validas = [...new Set(chips.split(","))].filter((k) => seriesData[k]).slice(0, MAX_SERIES);
|
||||
if (validas.length >= MIN_SERIES) setSelectedSeries(validas);
|
||||
}, [seriesData]);
|
||||
|
||||
const toggleSeries = (seriesKey) => {
|
||||
if (selectedSeries.includes(seriesKey)) {
|
||||
if (selectedSeries.length > MIN_SERIES) setSelectedSeries(selectedSeries.filter((s) => s !== seriesKey));
|
||||
} else if (selectedSeries.length < MAX_SERIES) {
|
||||
setSelectedSeries([...selectedSeries, seriesKey]);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleCategory = (category) => {
|
||||
setCollapsedCategories({ ...collapsedCategories, [category]: !collapsedCategories[category] });
|
||||
};
|
||||
|
||||
const renderValue = (value) => {
|
||||
if (!value || value === "Não" || value === "No") return <span className="text-muted">{isEn ? "No" : "Não"}</span>;
|
||||
if (value === "Sim" || value === "Yes") {
|
||||
return (
|
||||
<span className="inline-flex items-center gap-1.5 font-medium text-ok">
|
||||
<Check className="h-4 w-4" aria-hidden="true" />
|
||||
{isEn ? "Yes" : "Sim"}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return <span className="font-medium text-ink">{value}</span>;
|
||||
};
|
||||
|
||||
const valores = (key) => selectedSeries.map((k) => String(valorDe(seriesData[k], key) ?? (isEn ? "No" : "Não")));
|
||||
const diferem = (key) => new Set(valores(key)).size > 1;
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
<Header />
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
isEn={isEn}
|
||||
trail={[{ label: isEn ? "Comparator" : "Comparador" }]}
|
||||
icon={Scale}
|
||||
label={isEn ? "Up to four series side by side" : "Até quatro séries lado a lado"}
|
||||
title={isEn ? "ESP32 Series Comparator" : "Comparador de séries"}
|
||||
lede={
|
||||
isEn
|
||||
? "Put cores, radio, memory, peripherals, and security in the same table and see what really changes from chip to chip."
|
||||
: "Coloque núcleos, rádio, memória, periféricos e segurança na mesma tabela e veja o que realmente muda de um chip para outro."
|
||||
}
|
||||
/>
|
||||
|
||||
<section className="shell pt-10 sm:pt-12" aria-labelledby="escolha-titulo">
|
||||
<div className="panel p-5 sm:p-7">
|
||||
<div className="flex flex-wrap items-end justify-between gap-3">
|
||||
<div>
|
||||
<h2 id="escolha-titulo" className="text-base font-semibold text-ink">
|
||||
{isEn ? (
|
||||
<>Choose {MIN_SERIES} to {MAX_SERIES} series</>
|
||||
) : (
|
||||
<>Escolha de {MIN_SERIES} a {MAX_SERIES} séries</>
|
||||
)}
|
||||
</h2>
|
||||
<p role="status" aria-live="polite" className="mt-1 text-sm text-muted">
|
||||
{isEn ? (
|
||||
<>
|
||||
{selectedSeries.length} of {MAX_SERIES} selected
|
||||
{selectedSeries.length === MAX_SERIES && ". Remove one to switch."}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{selectedSeries.length} de {MAX_SERIES} selecionadas
|
||||
{selectedSeries.length === MAX_SERIES && ". Remova uma para trocar."}
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 flex flex-wrap gap-2">
|
||||
{series.map(([key]) => {
|
||||
const marcada = selectedSeries.includes(key);
|
||||
const bloqueada = !marcada && selectedSeries.length >= MAX_SERIES;
|
||||
return (
|
||||
<button
|
||||
key={key}
|
||||
type="button"
|
||||
onClick={() => toggleSeries(key)}
|
||||
aria-pressed={marcada}
|
||||
aria-disabled={bloqueada}
|
||||
className={`chip-btn ${bloqueada ? "opacity-50" : ""}`}
|
||||
>
|
||||
{marcada && <Check className="h-4 w-4" aria-hidden="true" />}
|
||||
{key}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="shell mt-8" aria-labelledby="tabela-titulo">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<h2 id="tabela-titulo" className="text-base font-semibold text-ink">
|
||||
{isEn ? "Specifications" : "Especificações"}
|
||||
</h2>
|
||||
<label className="flex min-h-11 cursor-pointer items-center gap-2.5 text-sm font-medium text-ink-soft">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={soDiferencas}
|
||||
onChange={(e) => setSoDiferencas(e.target.checked)}
|
||||
className="h-5 w-5 cursor-pointer accent-[var(--accent)]"
|
||||
/>
|
||||
{isEn ? "Show differences only" : "Mostrar só as diferenças"}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="panel mt-3 overflow-hidden">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full min-w-[30rem] border-collapse text-sm">
|
||||
<caption className="sr-only">
|
||||
{isEn ? (
|
||||
<>Comparison of series {selectedSeries.join(", ")}</>
|
||||
) : (
|
||||
<>Comparação das séries {selectedSeries.join(", ")}</>
|
||||
)}
|
||||
</caption>
|
||||
<thead>
|
||||
<tr className="border-b border-line bg-surface-2">
|
||||
<th scope="col" className="sticky left-0 z-20 w-28 bg-surface-2 px-4 py-4 text-left font-semibold text-muted sm:w-52 sm:px-6">
|
||||
{isEn ? "Specification" : "Especificação"}
|
||||
</th>
|
||||
{selectedSeries.map((seriesKey) => (
|
||||
<th key={seriesKey} scope="col" className="min-w-40 px-4 py-4 text-left sm:px-6">
|
||||
<Link href={getLocalizedHref(`/series/${seriesKey}`, currentLocale)} className="inline-flex min-h-11 items-center gap-1 font-display text-lg font-semibold tracking-[-0.03em] text-ink hover:text-accent">
|
||||
{seriesKey}
|
||||
<ArrowUpRight className="h-4 w-4 text-muted" aria-hidden="true" />
|
||||
</Link>
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{compareFields.map(({ category, fields }) => {
|
||||
const visiveis = soDiferencas ? fields.filter(({ key }) => diferem(key)) : fields;
|
||||
if (soDiferencas && visiveis.length === 0) return null;
|
||||
const isCollapsed = collapsedCategories[category] && !soDiferencas;
|
||||
return (
|
||||
<Fragment key={category}>
|
||||
<tr className="border-y border-line bg-surface-2/60">
|
||||
<th scope="rowgroup" colSpan={selectedSeries.length + 1} className="p-0 text-left">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => toggleCategory(category)}
|
||||
aria-expanded={!isCollapsed}
|
||||
className="flex min-h-12 w-full cursor-pointer items-center justify-between gap-3 px-4 py-3 text-left font-semibold text-ink sm:px-6"
|
||||
>
|
||||
<span className="sticky left-4 sm:left-6">{category}</span>
|
||||
<ChevronDown className={`h-4 w-4 shrink-0 text-muted transition-transform ${isCollapsed ? "" : "rotate-180"}`} aria-hidden="true" />
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
{!isCollapsed &&
|
||||
visiveis.map(({ key, label }) => (
|
||||
<tr key={key} className="border-b border-line last:border-b-0 hover:bg-surface-2/50">
|
||||
<th scope="row" className="sticky left-0 z-10 bg-surface px-4 py-3.5 text-left align-top font-medium text-muted sm:px-6">
|
||||
{label}
|
||||
</th>
|
||||
{selectedSeries.map((seriesKey) => (
|
||||
<td key={seriesKey} className="px-4 py-3.5 align-top sm:px-6">
|
||||
{renderValue(valorDe(seriesData[seriesKey], key))}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="shell section" aria-labelledby="docs-titulo">
|
||||
<h2 id="docs-titulo" className="section-title">
|
||||
{isEn ? "Official documentation" : "Documentação oficial"}
|
||||
</h2>
|
||||
<div className="mt-6 grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{selectedSeries.map((seriesKey) => {
|
||||
const seriesItem = seriesData[seriesKey];
|
||||
return (
|
||||
<div key={seriesKey} className="card flex flex-col justify-between gap-5 p-5">
|
||||
<Link href={getLocalizedHref(`/series/${seriesKey}`, currentLocale)} className="inline-flex min-h-11 items-center font-display text-lg font-semibold tracking-[-0.03em] text-ink hover:text-accent">
|
||||
{seriesKey}
|
||||
</Link>
|
||||
{seriesItem.datasheet ? (
|
||||
<a href={seriesItem.datasheet} target="_blank" rel="noopener noreferrer" className="btn btn-ghost btn-sm">
|
||||
{isEn ? "Official datasheet" : "Datasheet oficial"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
<span className="sr-only"> {isEn ? "(opens in a new tab)" : "(abre em nova aba)"}</span>
|
||||
</a>
|
||||
) : (
|
||||
<span className="text-sm text-muted">
|
||||
{isEn ? "Datasheet not yet published" : "Datasheet ainda não publicado"}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="panel mt-10 flex flex-col items-start justify-between gap-6 p-7 sm:p-10 md:flex-row md:items-center">
|
||||
<div className="max-w-2xl">
|
||||
<h2 className="section-title">
|
||||
{isEn ? "Want to test on the bench?" : "Quer testar na bancada?"}
|
||||
</h2>
|
||||
<p className="mt-3 text-base text-muted">
|
||||
{isEn
|
||||
? "Explore development boards with pinouts, peripherals, and official store links."
|
||||
: "Veja as placas de desenvolvimento com pinagem, periféricos e link para a loja."}
|
||||
</p>
|
||||
</div>
|
||||
<Link href={getLocalizedHref("/catalogo", currentLocale)} className="btn btn-primary shrink-0">
|
||||
{isEn ? "View boards catalog" : "Ver catálogo de placas"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
return paginaMeta({
|
||||
titulo: isEn
|
||||
? "ESP Component Registry & IDF Component Manager · ESPDocs"
|
||||
: "ESP Component Registry & IDF Component Manager · ESPDocs",
|
||||
descricao: isEn
|
||||
? "Official interactive catalog of the ESP Component Registry: display drivers, LVGL, ESP-SR voice recognition, RainMaker, BSPs, and idf_component.yml generator."
|
||||
: "Catálogo oficial e interativo do ESP Component Registry: drivers de displays, LVGL, reconhecimento de voz ESP-SR, RainMaker, BSPs e gerador de idf_component.yml.",
|
||||
caminho: "/componentes",
|
||||
locale,
|
||||
keywords: isEn
|
||||
? [
|
||||
"ESP Component Registry",
|
||||
"IDF Component Manager",
|
||||
"idf_component.yml",
|
||||
"idf.py add-dependency",
|
||||
"ESP32 components",
|
||||
"espressif esp_lvgl_port",
|
||||
"espressif esp_rainmaker",
|
||||
"espressif esp-sr",
|
||||
"ESP-IDF libraries",
|
||||
]
|
||||
: [
|
||||
"ESP Component Registry",
|
||||
"IDF Component Manager",
|
||||
"idf_component.yml",
|
||||
"idf.py add-dependency",
|
||||
"componentes ESP32",
|
||||
"espressif esp_lvgl_port",
|
||||
"espressif esp_rainmaker",
|
||||
"espressif esp-sr",
|
||||
"bibliotecas ESP-IDF",
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
const faqsPt = [
|
||||
{
|
||||
pergunta: "O que é o ESP Component Registry e o IDF Component Manager?",
|
||||
resposta: "O ESP Component Registry (components.espressif.com) é o repositório oficial de pacotes modulares da Espressif. O IDF Component Manager é a ferramenta integrada ao ESP-IDF (a partir do v4.4 e padrão no v5.x+) que baixa, compila e resolve versões de dependências automaticamente a partir do manifesto idf_component.yml.",
|
||||
},
|
||||
{
|
||||
pergunta: "Como adicionar um componente ao meu projeto ESP-IDF?",
|
||||
resposta: "Você pode executar o comando 'idf.py add-dependency \"namespace/componente^versao\"' no terminal do projeto (por exemplo: idf.py add-dependency \"espressif/esp_lvgl_port^2.4.0\") ou editar diretamente o arquivo main/idf_component.yml.",
|
||||
},
|
||||
{
|
||||
pergunta: "Qual a diferença entre usar o Component Registry e git submodules?",
|
||||
resposta: "O Component Registry elimina a complexidade de gerenciar submódulos Git pesados e versões manuais. Ele oferece versionamento semântico (^ e ~), resolução automática de dependências transitivas e compilação modular sob demanda.",
|
||||
},
|
||||
{
|
||||
pergunta: "Posso criar e publicar meus próprios componentes?",
|
||||
resposta: "Sim, qualquer desenvolvedor ou empresa pode publicar componentes públicos ou privados no ESP Component Registry utilizando a ferramenta oficial Compote CLI (pip install idf-component-manager).",
|
||||
},
|
||||
];
|
||||
|
||||
const faqsEn = [
|
||||
{
|
||||
pergunta: "What is the ESP Component Registry and IDF Component Manager?",
|
||||
resposta: "The ESP Component Registry (components.espressif.com) is the official central repository for modular Espressif packages. The IDF Component Manager is integrated into ESP-IDF (v4.4+ and default in v5.x+) to automatically download, compile, and resolve dependency versions from an idf_component.yml manifest.",
|
||||
},
|
||||
{
|
||||
pergunta: "How to add a component to an ESP-IDF project?",
|
||||
resposta: "You can run 'idf.py add-dependency \"namespace/component^version\"' in your project terminal (for example: idf.py add-dependency \"espressif/esp_lvgl_port^2.4.0\") or edit main/idf_component.yml directly.",
|
||||
},
|
||||
{
|
||||
pergunta: "What is the difference between using Component Registry and git submodules?",
|
||||
resposta: "The Component Registry eliminates the complexity of managing heavy Git submodules and manual tracking. It provides semantic versioning (^ and ~), automatic transitive dependency resolution, and modular on-demand compilation.",
|
||||
},
|
||||
{
|
||||
pergunta: "Can I create and publish my own components?",
|
||||
resposta: "Yes, any developer or company can publish public or private components to the ESP Component Registry using the official Compote CLI tool (pip install idf-component-manager).",
|
||||
},
|
||||
];
|
||||
|
||||
export default async function ComponentesLayout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const faqs = isEn ? faqsEn : faqsPt;
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: isEn ? "Home" : "Início", caminho: isEn ? "/en" : "/" },
|
||||
{ nome: "ESP Component Registry", caminho: isEn ? "/en/components" : "/componentes" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.perguntas(faqs)),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.aplicacaoWeb({
|
||||
nome: isEn ? "ESP Component Registry Hub & Manifest Builder" : "Hub do ESP Component Registry & Construtor de Manifesto",
|
||||
descricao: isEn
|
||||
? "Curated catalog and idf_component.yml manifest generator for modular ESP-IDF components."
|
||||
: "Catálogo curado e gerador de manifesto idf_component.yml para componentes modulares do ESP-IDF.",
|
||||
caminho: isEn ? "/en/components" : "/componentes",
|
||||
locale,
|
||||
})
|
||||
),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useMemo } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import SectionHead from "@/components/SectionHead";
|
||||
import {
|
||||
CATEGORIAS_COMPONENTES,
|
||||
COMPONENTES_REGISTRY,
|
||||
GUIA_COMPONENT_MANAGER
|
||||
} from "@/lib/componentRegistryData";
|
||||
import * as componentesPt from "@/lib/componentRegistryData";
|
||||
import * as componentesEn from "@/lib/data/en/componentes";
|
||||
import {
|
||||
ArrowUpRight,
|
||||
Box,
|
||||
@@ -44,6 +42,10 @@ const ICONES_CATEGORIA = {
|
||||
};
|
||||
|
||||
export default function ComponentRegistryPage() {
|
||||
const pathname = usePathname();
|
||||
const isEn = pathname?.startsWith("/en");
|
||||
const { CATEGORIAS_COMPONENTES, COMPONENTES_REGISTRY, GUIA_COMPONENT_MANAGER } = isEn ? componentesEn : componentesPt;
|
||||
|
||||
const [busca, setBusca] = useState("");
|
||||
const [categoriaAtiva, setCategoriaAtiva] = useState("todos");
|
||||
const [chipFiltro, setChipFiltro] = useState("todos");
|
||||
@@ -74,7 +76,7 @@ export default function ComponentRegistryPage() {
|
||||
|
||||
return matchCategoria && matchChip && matchBusca;
|
||||
});
|
||||
}, [busca, categoriaAtiva, chipFiltro]);
|
||||
}, [busca, categoriaAtiva, chipFiltro, COMPONENTES_REGISTRY]);
|
||||
|
||||
// Manipuladores de cópia
|
||||
const copiarComando = (id, comando) => {
|
||||
@@ -96,15 +98,19 @@ export default function ComponentRegistryPage() {
|
||||
);
|
||||
|
||||
if (selecionados.length === 0) {
|
||||
return `# Nenhum componente selecionado.\n# Clique em "+ Adicionar ao Manifesto" nos cards abaixo.`;
|
||||
return isEn
|
||||
? `# No components selected.\n# Click "+ Add to Manifest" on the cards below.`
|
||||
: `# Nenhum componente selecionado.\n# Clique em "+ Adicionar ao Manifesto" nos cards abaixo.`;
|
||||
}
|
||||
|
||||
let yaml = `# main/idf_component.yml\n# Gerado via ESPDocs Component Hub (https://espdocs.cienciaembarcada.com.br/componentes)\n\ndependencies:\n`;
|
||||
let yaml = isEn
|
||||
? `# main/idf_component.yml\n# Generated via ESPDocs Component Hub (https://espdocs.cienciaembarcada.com.br/en/components)\n\ndependencies:\n`
|
||||
: `# main/idf_component.yml\n# Gerado via ESPDocs Component Hub (https://espdocs.cienciaembarcada.com.br/componentes)\n\ndependencies:\n`;
|
||||
selecionados.forEach((c) => {
|
||||
yaml += ` ${c.namespace}/${c.name}: "${c.versao}"\n`;
|
||||
});
|
||||
return yaml;
|
||||
}, [componentesSelecionados]);
|
||||
}, [componentesSelecionados, COMPONENTES_REGISTRY, isEn]);
|
||||
|
||||
const copiarManifesto = () => {
|
||||
navigator.clipboard.writeText(manifestoYaml);
|
||||
@@ -138,40 +144,47 @@ export default function ComponentRegistryPage() {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Component Registry" }]}
|
||||
isEn={isEn}
|
||||
trail={[{ label: isEn ? "Component Registry" : "Component Registry" }]}
|
||||
icon={Box}
|
||||
label="ESP-IDF Component Manager"
|
||||
title="ESP Component Registry"
|
||||
lede="O catálogo oficial de pacotes reutilizáveis da Espressif para o ESP-IDF. Escolha drivers, voz e pilhas industriais, copie o comando e gere o manifesto do projeto."
|
||||
lede={
|
||||
isEn
|
||||
? "Official Espressif catalog of reusable packages for ESP-IDF. Choose drivers, voice stacks, and industrial protocols, copy commands, and generate project manifests."
|
||||
: "O catálogo oficial de pacotes reutilizáveis da Espressif para o ESP-IDF. Escolha drivers, voz e pilhas industriais, copie o comando e gere o manifesto do projeto."
|
||||
}
|
||||
>
|
||||
<a href="https://components.espressif.com" target="_blank" rel="noopener noreferrer" className="btn btn-primary">
|
||||
Abrir o registro oficial
|
||||
{isEn ? "Open official registry" : "Abrir o registro oficial"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
<span className="sr-only"> (abre em nova aba)</span>
|
||||
<span className="sr-only"> {isEn ? "(opens in a new tab)" : "(abre em nova aba)"}</span>
|
||||
</a>
|
||||
<a href="#manifesto-builder" className="btn btn-ghost">
|
||||
Gerar idf_component.yml
|
||||
{isEn ? "Generate idf_component.yml" : "Gerar idf_component.yml"}
|
||||
</a>
|
||||
</PageHero>
|
||||
|
||||
<section className="shell pt-10 sm:pt-12" aria-label="Busca e filtros">
|
||||
<section className="shell pt-10 sm:pt-12" aria-label={isEn ? "Search and filters" : "Busca e filtros"}>
|
||||
<div className="panel p-5 sm:p-6">
|
||||
<div className="relative">
|
||||
<label htmlFor="busca-componente" className="sr-only">Buscar por nome, namespace ou tag</label>
|
||||
<label htmlFor="busca-componente" className="sr-only">
|
||||
{isEn ? "Search by name, namespace, or tag" : "Buscar por nome, namespace ou tag"}
|
||||
</label>
|
||||
<Search className="pointer-events-none absolute left-4 top-1/2 h-5 w-5 -translate-y-1/2 text-muted" aria-hidden="true" />
|
||||
<input
|
||||
id="busca-componente"
|
||||
type="search"
|
||||
value={busca}
|
||||
onChange={(e) => setBusca(e.target.value)}
|
||||
placeholder="Buscar por nome, namespace ou tag"
|
||||
placeholder={isEn ? "Search by name, namespace, or tag" : "Buscar por nome, namespace ou tag"}
|
||||
autoComplete="off"
|
||||
className="field pl-12 pr-4 text-base"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mt-5">
|
||||
<h2 className="text-sm font-semibold text-ink">Categoria</h2>
|
||||
<h2 className="text-sm font-semibold text-ink">{isEn ? "Category" : "Categoria"}</h2>
|
||||
<div className="mt-3 flex flex-wrap gap-2">
|
||||
{CATEGORIAS_COMPONENTES.map((cat) => {
|
||||
const Icone = ICONES_CATEGORIA[cat.id] ?? Layers;
|
||||
@@ -179,7 +192,7 @@ export default function ComponentRegistryPage() {
|
||||
return (
|
||||
<button key={cat.id} type="button" onClick={() => setCategoriaAtiva(cat.id)} aria-pressed={categoriaAtiva === cat.id} className="chip-btn">
|
||||
<Icone className="h-4 w-4" aria-hidden="true" />
|
||||
{cat.id === "todos" ? "Todos" : cat.nome.replace(/\s*\(.*\)/, "").split(",")[0].split(" &")[0]}
|
||||
{cat.id === "todos" ? (isEn ? "All" : "Todos") : cat.nome.replace(/\s*\(.*\)/, "").split(",")[0].split(" &")[0]}
|
||||
<span className="tabular-nums opacity-80">{contagem}</span>
|
||||
</button>
|
||||
);
|
||||
@@ -188,11 +201,11 @@ export default function ComponentRegistryPage() {
|
||||
</div>
|
||||
|
||||
<div className="mt-5 border-t border-line pt-5">
|
||||
<h2 className="text-sm font-semibold text-ink">Chip compatível</h2>
|
||||
<h2 className="text-sm font-semibold text-ink">{isEn ? "Compatible chip" : "Chip compatível"}</h2>
|
||||
<div className="mt-3 flex flex-wrap gap-2">
|
||||
{chipsDisponiveis.map((chip) => (
|
||||
<button key={chip} type="button" onClick={() => setChipFiltro(chip)} aria-pressed={chipFiltro === chip} className="chip-btn">
|
||||
{chip === "todos" ? "Todos" : chip}
|
||||
{chip === "todos" ? (isEn ? "All" : "Todos") : chip}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -203,17 +216,17 @@ export default function ComponentRegistryPage() {
|
||||
<section className="shell section pt-8 sm:pt-10" aria-labelledby="lista-titulo">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<h2 id="lista-titulo" role="status" aria-live="polite" className="text-base font-semibold text-ink">
|
||||
{componentesFiltrados.length} {componentesFiltrados.length === 1 ? "componente" : "componentes"}
|
||||
{componentesFiltrados.length} {componentesFiltrados.length === 1 ? (isEn ? "component" : "componente") : (isEn ? "components" : "componentes")}
|
||||
</h2>
|
||||
<div className="flex flex-wrap items-center gap-x-5 gap-y-1">
|
||||
{totalFiltros > 0 && (
|
||||
<button type="button" onClick={limparFiltros} className="inline-flex min-h-11 items-center gap-1.5 text-sm font-medium text-accent hover:text-accent-strong">
|
||||
<X className="h-4 w-4" aria-hidden="true" />
|
||||
Limpar filtros
|
||||
{isEn ? "Clear filters" : "Limpar filtros"}
|
||||
</button>
|
||||
)}
|
||||
<a href="#manifesto-builder" className="inline-flex min-h-11 items-center gap-1.5 text-sm font-medium text-accent hover:text-accent-strong">
|
||||
Manifesto: {componentesSelecionados.length} {componentesSelecionados.length === 1 ? "componente" : "componentes"}
|
||||
{isEn ? "Manifest:" : "Manifesto:"} {componentesSelecionados.length} {componentesSelecionados.length === 1 ? (isEn ? "component" : "componente") : (isEn ? "components" : "componentes")}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -221,9 +234,15 @@ export default function ComponentRegistryPage() {
|
||||
{componentesFiltrados.length === 0 ? (
|
||||
<div className="card mt-6 px-6 py-14 text-center">
|
||||
<Box className="mx-auto h-10 w-10 text-muted" aria-hidden="true" />
|
||||
<h3 className="mt-4 font-display text-xl font-semibold text-ink">Nenhum componente encontrado</h3>
|
||||
<p className="mx-auto mt-2 max-w-md text-sm text-muted">Busque por um termo mais geral ou volte para todas as categorias.</p>
|
||||
<button type="button" onClick={limparFiltros} className="btn btn-primary mt-6">Limpar filtros</button>
|
||||
<h3 className="mt-4 font-display text-xl font-semibold text-ink">
|
||||
{isEn ? "No components found" : "Nenhum componente encontrado"}
|
||||
</h3>
|
||||
<p className="mx-auto mt-2 max-w-md text-sm text-muted">
|
||||
{isEn ? "Search for a more general term or return to all categories." : "Busque por um termo mais geral ou volte para todas as categorias."}
|
||||
</p>
|
||||
<button type="button" onClick={limparFiltros} className="btn btn-primary mt-6">
|
||||
{isEn ? "Clear filters" : "Limpar filtros"}
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="mt-6 grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
@@ -242,7 +261,7 @@ export default function ComponentRegistryPage() {
|
||||
{comp.oficial && (
|
||||
<span className="chip chip-accent px-2 py-0">
|
||||
<ShieldCheck className="h-3 w-3" aria-hidden="true" />
|
||||
Oficial
|
||||
{isEn ? "Official" : "Oficial"}
|
||||
</span>
|
||||
)}
|
||||
</p>
|
||||
@@ -266,12 +285,12 @@ export default function ComponentRegistryPage() {
|
||||
type="button"
|
||||
onClick={() => copiarComando(comp.id, cliCmd)}
|
||||
className="code-panel flex w-full min-h-11 items-center justify-between gap-3 rounded-lg px-3 py-2 text-left font-mono text-xs transition-colors hover:border-white/30"
|
||||
aria-label={`Copiar comando para adicionar ${comp.name}`}
|
||||
aria-label={isEn ? `Copy command to add ${comp.name}` : `Copiar comando para adicionar ${comp.name}`}
|
||||
>
|
||||
<span className="truncate text-[#e9eef4]">{cliCmd}</span>
|
||||
{foiCopiado ? <Check className="h-4 w-4 shrink-0 text-[#5fe0a2]" aria-hidden="true" /> : <Copy className="h-4 w-4 shrink-0 text-[#a6afbd]" aria-hidden="true" />}
|
||||
</button>
|
||||
<p role="status" className="sr-only">{foiCopiado ? "Comando copiado" : ""}</p>
|
||||
<p role="status" className="sr-only">{foiCopiado ? (isEn ? "Command copied" : "Comando copiado") : ""}</p>
|
||||
|
||||
<p className="mt-3 text-xs text-muted">
|
||||
<span className="font-medium text-ink-soft">Chips: </span>
|
||||
@@ -287,14 +306,14 @@ export default function ComponentRegistryPage() {
|
||||
className={`btn btn-sm ${selecionado ? "btn-primary" : "btn-ghost"}`}
|
||||
>
|
||||
{selecionado ? <Check className="h-4 w-4" aria-hidden="true" /> : <Plus className="h-4 w-4" aria-hidden="true" />}
|
||||
{selecionado ? "No manifesto" : "Adicionar ao manifesto"}
|
||||
{selecionado ? (isEn ? "In manifest" : "No manifesto") : (isEn ? "Add to manifest" : "Adicionar ao manifesto")}
|
||||
</button>
|
||||
<a
|
||||
href={comp.urlRegistry}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="btn-icon inline-flex h-11 w-11 items-center justify-center rounded-full text-muted transition-colors hover:bg-surface-2 hover:text-accent"
|
||||
aria-label={`Abrir ${comp.name} no registro oficial (nova aba)`}
|
||||
aria-label={isEn ? `Open ${comp.name} in official registry (new tab)` : `Abrir ${comp.name} no registro oficial (nova aba)`}
|
||||
>
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
@@ -310,37 +329,42 @@ export default function ComponentRegistryPage() {
|
||||
<div className="panel p-6 sm:p-9">
|
||||
<div className="flex flex-col justify-between gap-5 md:flex-row md:items-end">
|
||||
<div className="max-w-2xl">
|
||||
<p className="eyebrow">Gerador de manifesto</p>
|
||||
<h2 id="manifesto-titulo" className="section-title mt-3">Seu idf_component.yml</h2>
|
||||
<p className="eyebrow">{isEn ? "Manifest generator" : "Gerador de manifesto"}</p>
|
||||
<h2 id="manifesto-titulo" className="section-title mt-3">
|
||||
{isEn ? "Your idf_component.yml" : "Seu idf_component.yml"}
|
||||
</h2>
|
||||
<p className="mt-3 text-sm leading-relaxed text-muted">
|
||||
Salve o arquivo na pasta <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono">main/</code> do projeto e o
|
||||
ESP-IDF baixa todas as bibliotecas na compilação.
|
||||
{isEn ? (
|
||||
<>Save this file in your project's <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono">main/</code> folder and ESP-IDF will download all dependencies during build.</>
|
||||
) : (
|
||||
<>Salve o arquivo na pasta <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono">main/</code> do projeto e o ESP-IDF baixa todas as bibliotecas na compilação.</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<button type="button" onClick={copiarManifesto} className="btn btn-primary btn-sm">
|
||||
{manifestoCopiado ? <Check className="h-4 w-4" aria-hidden="true" /> : <Copy className="h-4 w-4" aria-hidden="true" />}
|
||||
<span role="status">{manifestoCopiado ? "Copiado" : "Copiar YAML"}</span>
|
||||
<span role="status">{manifestoCopiado ? (isEn ? "Copied" : "Copiado") : (isEn ? "Copy YAML" : "Copiar YAML")}</span>
|
||||
</button>
|
||||
<button type="button" onClick={baixarManifesto} className="btn btn-ghost btn-sm">
|
||||
<Download className="h-4 w-4" aria-hidden="true" />
|
||||
Baixar .yml
|
||||
{isEn ? "Download .yml" : "Baixar .yml"}
|
||||
</button>
|
||||
{componentesSelecionados.length > 0 && (
|
||||
<button type="button" onClick={() => setComponentesSelecionados([])} className="btn btn-ghost btn-sm">
|
||||
<Trash2 className="h-4 w-4" aria-hidden="true" />
|
||||
Limpar
|
||||
{isEn ? "Clear" : "Limpar"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="code-panel mt-6">
|
||||
<pre tabIndex={0} aria-label="Conteúdo do idf_component.yml" className="!text-sm"><code className="text-[#e9eef4]">{manifestoYaml}</code></pre>
|
||||
<pre tabIndex={0} aria-label={isEn ? "Content of idf_component.yml" : "Conteúdo do idf_component.yml"} className="!text-sm"><code className="text-[#e9eef4]">{manifestoYaml}</code></pre>
|
||||
</div>
|
||||
|
||||
{componentesSelecionados.length > 0 && (
|
||||
<ul className="mt-5 flex flex-wrap items-center gap-2" aria-label="Componentes incluídos">
|
||||
<ul className="mt-5 flex flex-wrap items-center gap-2" aria-label={isEn ? "Included components" : "Componentes incluídos"}>
|
||||
{componentesSelecionados.map((id) => {
|
||||
const c = COMPONENTES_REGISTRY.find((item) => item.id === id);
|
||||
if (!c) return null;
|
||||
@@ -351,7 +375,7 @@ export default function ComponentRegistryPage() {
|
||||
type="button"
|
||||
onClick={() => toggleSelecaoManifesto(id)}
|
||||
className="-my-2 grid h-11 w-11 place-items-center rounded-full hover:bg-accent/15"
|
||||
aria-label={`Remover ${c.name} do manifesto`}
|
||||
aria-label={isEn ? `Remove ${c.name} from manifest` : `Remover ${c.name} do manifesto`}
|
||||
>
|
||||
<X className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
</button>
|
||||
@@ -364,7 +388,7 @@ export default function ComponentRegistryPage() {
|
||||
</section>
|
||||
|
||||
<section className="shell section border-t border-line pt-14" aria-labelledby="guia-titulo">
|
||||
<SectionHead id="guia-titulo" eyebrow="Guia rápido" title={GUIA_COMPONENT_MANAGER.titulo} lede={GUIA_COMPONENT_MANAGER.resumo} />
|
||||
<SectionHead id="guia-titulo" eyebrow={isEn ? "Quick guide" : "Guia rápido"} title={GUIA_COMPONENT_MANAGER.titulo} lede={GUIA_COMPONENT_MANAGER.resumo} />
|
||||
|
||||
<ul className="mt-8 grid gap-3 md:grid-cols-2 lg:grid-cols-4">
|
||||
{GUIA_COMPONENT_MANAGER.vantagens.map((v) => (
|
||||
@@ -377,7 +401,7 @@ export default function ComponentRegistryPage() {
|
||||
|
||||
<h3 className="mt-12 flex items-center gap-2 font-display text-xl font-semibold tracking-[-0.03em] text-ink">
|
||||
<Terminal className="h-5 w-5 text-accent" aria-hidden="true" />
|
||||
Comandos essenciais
|
||||
{isEn ? "Essential commands" : "Comandos essenciais"}
|
||||
</h3>
|
||||
<ul className="mt-4 space-y-3">
|
||||
{GUIA_COMPONENT_MANAGER.comandosCli.map((cmd, i) => (
|
||||
@@ -392,7 +416,7 @@ export default function ComponentRegistryPage() {
|
||||
className="inline-flex min-h-11 shrink-0 items-center gap-1.5 self-start rounded-full border border-white/15 px-4 text-sm font-medium text-[#e9eef4] transition-colors hover:bg-white/10 md:self-auto"
|
||||
>
|
||||
{copiadoId === `cmd-${i}` ? <Check className="h-4 w-4 text-[#5fe0a2]" aria-hidden="true" /> : <Copy className="h-4 w-4" aria-hidden="true" />}
|
||||
{copiadoId === `cmd-${i}` ? "Copiado" : "Copiar"}
|
||||
{copiadoId === `cmd-${i}` ? (isEn ? "Copied" : "Copiado") : (isEn ? "Copy" : "Copiar")}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
@@ -401,13 +425,24 @@ export default function ComponentRegistryPage() {
|
||||
<div className="callout mt-8">
|
||||
<h3 className="flex items-center gap-2 font-semibold text-ink">
|
||||
<HelpCircle className="h-4 w-4 text-accent" aria-hidden="true" />
|
||||
Versionamento semântico no ESP-IDF
|
||||
{isEn ? "Semantic versioning in ESP-IDF" : "Versionamento semântico no ESP-IDF"}
|
||||
</h3>
|
||||
<ul className="mt-2 list-disc space-y-1.5 pl-5">
|
||||
<li><code>^1.2.0</code>: aceita atualizações menores e correções (1.2.1, 1.3.0), mas bloqueia mudanças grandes de API (2.0.0). <strong>Recomendado.</strong></li>
|
||||
<li><code>~1.2.0</code>: aceita só correções de bugs (1.2.1, 1.2.5).</li>
|
||||
<li><code>1.2.0</code>: trava na versão exata.</li>
|
||||
<li><code>*</code>: aceita qualquer versão. Evite em produção.</li>
|
||||
{isEn ? (
|
||||
<>
|
||||
<li><code>^1.2.0</code>: accepts minor updates and bug fixes (1.2.1, 1.3.0), but blocks breaking API changes (2.0.0). <strong>Recommended.</strong></li>
|
||||
<li><code>~1.2.0</code>: accepts patch releases only (1.2.1, 1.2.5).</li>
|
||||
<li><code>1.2.0</code>: locks to this exact version.</li>
|
||||
<li><code>*</code>: accepts any version. Avoid in production.</li>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<li><code>^1.2.0</code>: aceita atualizações menores e correções (1.2.1, 1.3.0), mas bloqueia mudanças grandes de API (2.0.0). <strong>Recomendado.</strong></li>
|
||||
<li><code>~1.2.0</code>: aceita só correções de bugs (1.2.1, 1.2.5).</li>
|
||||
<li><code>1.2.0</code>: trava na versão exata.</li>
|
||||
<li><code>*</code>: aceita qualquer versão. Evite em produção.</li>
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,121 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
return paginaMeta({
|
||||
titulo: isEn
|
||||
? "Common ESP32 Errors & Diagnostics: Professional Guide"
|
||||
: "Diagnóstico de Erros Comuns no ESP32: Guia Profissional",
|
||||
descricao: isEn
|
||||
? "Definitive technical guide to identify and fix Brownout, Guru Meditation, Task Watchdog, Stack Overflow, memory leaks, and boot issues on ESP32 (Arduino & ESP-IDF)."
|
||||
: "Guia técnico definitivo para identificar e resolver Brownout, Guru Meditation, Task Watchdog, Stack Overflow, vazamento de memória e falhas de boot no ESP32 (Arduino e ESP-IDF).",
|
||||
caminho: "/diagnostico",
|
||||
locale,
|
||||
keywords: isEn
|
||||
? [
|
||||
"common ESP32 errors",
|
||||
"brownout detector was triggered",
|
||||
"guru meditation error",
|
||||
"task watchdog got triggered",
|
||||
"stack canary watchpoint triggered",
|
||||
"how to debug ESP32",
|
||||
"ESP32 bootloop rebooting",
|
||||
"failed to connect to esp32",
|
||||
]
|
||||
: [
|
||||
"erros comuns ESP32",
|
||||
"brownout detector was triggered",
|
||||
"guru meditation error",
|
||||
"task watchdog got triggered",
|
||||
"stack canary watchpoint triggered",
|
||||
"como debugar ESP32",
|
||||
"ESP32 reiniciando em loop",
|
||||
"failed to connect to esp32",
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
const faqsPt = [
|
||||
{
|
||||
pergunta: "O que causa o erro 'Brownout detector was triggered' no ESP32?",
|
||||
resposta: "Ocorre quando a tensão no pino 3V3 cai abaixo de 2.8V ~ 2.43V devido a picos rápidos de corrente do rádio Wi-Fi/BLE (superando 500mA), cabos USB finos ou regulador LDO inadequado. A solução de engenharia envolve adicionar capacitores Low-ESR de 10µF a 100µF próximos ao VCC e usar LDOs robustos de 600mA+.",
|
||||
},
|
||||
{
|
||||
pergunta: "Como resolver o 'Guru Meditation Error (LoadProhibited)'?",
|
||||
resposta: "LoadProhibited indica tentativa de acessar um ponteiro nulo (NULL) ou inválido na memória. A solução consiste em usar o Espressif Exception Decoder ou addr2line para localizar a linha exata no código e implementar validações defensivas como if (ponteiro != NULL).",
|
||||
},
|
||||
{
|
||||
pergunta: "Por que o Task Watchdog Timer (TWDT) dispara no FreeRTOS?",
|
||||
resposta: "O TWDT dispara quando uma tarefa de prioridade maior monopoliza a CPU em um loop bloqueante (ex: while(1) sem vTaskDelay), impedindo a tarefa IDLE de alimentar o watchdog do sistema operacional.",
|
||||
},
|
||||
{
|
||||
pergunta: "Por que conexões HTTPS e TLS falham com código -0x2700 no ESP32?",
|
||||
resposta: "Porque ao ligar, o ESP32 inicia o relógio interno no ano de 1970. O validador de certificados TLS considera o certificado do servidor inválido por estar no 'futuro'. Sincronizar o relógio via SNTP (configTime) antes da conexão resolve o problema.",
|
||||
},
|
||||
];
|
||||
|
||||
const faqsEn = [
|
||||
{
|
||||
pergunta: "What causes 'Brownout detector was triggered' on ESP32?",
|
||||
resposta: "It occurs when the 3V3 rail drops below 2.8V ~ 2.43V during rapid Wi-Fi/BLE radio current spikes (often exceeding 500mA), caused by thin USB cables or an undersized LDO regulator. The engineering solution involves placing 10µF to 100µF Low-ESR bypass capacitors near VCC and using 600mA+ robust LDO regulators.",
|
||||
},
|
||||
{
|
||||
pergunta: "How to resolve 'Guru Meditation Error (LoadProhibited)'?",
|
||||
resposta: "LoadProhibited indicates an attempt to read from or write to a null (NULL) or invalid memory address. The fix involves using the Espressif Exception Decoder or addr2line to pinpoint the source line and applying defensive checks such as if (ptr != NULL).",
|
||||
},
|
||||
{
|
||||
pergunta: "Why does the Task Watchdog Timer (TWDT) trigger in FreeRTOS?",
|
||||
resposta: "The TWDT triggers when a high-priority task monopolizes the CPU in a tight blocking loop (e.g. while(1) without vTaskDelay), starving the lower-priority IDLE task that feeds the operating system watchdog.",
|
||||
},
|
||||
{
|
||||
pergunta: "Why do HTTPS and TLS connections fail with error -0x2700 on ESP32?",
|
||||
resposta: "On boot, the ESP32 internal system clock starts at epoch year 1970. The TLS certificate validator rejects the server certificate because its validity dates appear in the distant 'future'. Synchronizing time via SNTP (configTime) prior to initiating TLS connections resolves the issue.",
|
||||
},
|
||||
];
|
||||
|
||||
export default async function DiagnosticoLayout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const faqs = isEn ? faqsEn : faqsPt;
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: isEn ? "Home" : "Início", caminho: isEn ? "/en" : "/" },
|
||||
{ nome: isEn ? "Diagnostics & Common Errors" : "Diagnóstico & Erros Comuns", caminho: isEn ? "/en/diagnostics" : "/diagnostico" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.perguntas(faqs)
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.aplicacaoWeb({
|
||||
nome: isEn ? "ESP32 Error Diagnostics & Debugging Guide" : "Guia de Diagnóstico e Erros no ESP32",
|
||||
descricao: isEn
|
||||
? "Technical guide and log decoder for troubleshooting CPU panics, crashes, and exceptions on ESP32."
|
||||
: "Ferramenta e guia técnico de análise de falhas, pânicos de CPU e decodificação de logs no ESP32.",
|
||||
caminho: isEn ? "/en/diagnostics" : "/diagnostico",
|
||||
locale,
|
||||
})
|
||||
),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,15 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useMemo, useRef } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import {
|
||||
categoriasDiagnostico,
|
||||
sintomasRapidos,
|
||||
errosCatalogo,
|
||||
regrasDecodificadorLog,
|
||||
} from "@/lib/diagnosticoData";
|
||||
import * as diagnosticoPt from "@/lib/diagnosticoData";
|
||||
import * as diagnosticoEn from "@/lib/data/en/diagnostico";
|
||||
import {
|
||||
Activity,
|
||||
AlertTriangle,
|
||||
@@ -38,19 +35,30 @@ const semEmoji = (texto) => texto.replace(/^[\p{Extended_Pictographic}\uFE0F\s]+
|
||||
|
||||
const ICONES = { Zap, Cpu, Layers, Activity, Terminal, Wifi };
|
||||
|
||||
const EXEMPLOS_LOG = [
|
||||
const EXEMPLOS_LOG_PT = [
|
||||
["Brownout", "Brownout detector was triggered\n\nrst:0xc (SW_CPU_RESET),boot:0x13"],
|
||||
["LoadProhibited", "Guru Meditation Error: Core 0 panic'ed (LoadProhibited).\nEXCVADDR: 0x00000000"],
|
||||
["Task watchdog", "Task watchdog got triggered. The following tasks/users did not reset the watchdog: - IDLE0"],
|
||||
["Handshake TLS", "mbedtls_ssl_handshake returned -0x2700\nThe certificate is not yet valid"],
|
||||
];
|
||||
|
||||
const EXEMPLOS_LOG_EN = [
|
||||
["Brownout", "Brownout detector was triggered\n\nrst:0xc (SW_CPU_RESET),boot:0x13"],
|
||||
["LoadProhibited", "Guru Meditation Error: Core 0 panic'ed (LoadProhibited).\nEXCVADDR: 0x00000000"],
|
||||
["Task watchdog", "Task watchdog got triggered. The following tasks/users did not reset the watchdog: - IDLE0"],
|
||||
["TLS Handshake", "mbedtls_ssl_handshake returned -0x2700\nThe certificate is not yet valid"],
|
||||
];
|
||||
|
||||
const GRAVIDADE = {
|
||||
"Crítica": "text-danger",
|
||||
"Critical": "text-danger",
|
||||
Alta: "text-gold",
|
||||
High: "text-gold",
|
||||
"Média": "text-accent",
|
||||
Medium: "text-accent",
|
||||
};
|
||||
|
||||
const CHECKLISTS = [
|
||||
const CHECKLISTS_PT = [
|
||||
{
|
||||
icon: Zap,
|
||||
titulo: "Hardware e alimentação",
|
||||
@@ -73,7 +81,36 @@ const CHECKLISTS = [
|
||||
},
|
||||
];
|
||||
|
||||
const CHECKLISTS_EN = [
|
||||
{
|
||||
icon: Zap,
|
||||
titulo: "Hardware and Power Supply",
|
||||
itens: [
|
||||
"10 µF to 100 µF low-ESR capacitor on VCC, plus a 100 nF ceramic capacitor close to the chip.",
|
||||
"LDO regulator sized for 600 mA to 1 A current spikes, with adequate thermal margin.",
|
||||
"No external peripherals forcing logic levels on strapping pins during reset and boot.",
|
||||
"10 µF or 1 µF capacitor on the EN (RST) pin for stable auto-reset flashing.",
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Layers,
|
||||
titulo: "Firmware and FreeRTOS",
|
||||
itens: [
|
||||
"Every FreeRTOS task yields CPU time with vTaskDelay, queues, or semaphores.",
|
||||
"Every ISR marked with IRAM_ATTR with zero blocking calls.",
|
||||
"Avoid continuous heap reallocations using Arduino Strings in tight loops.",
|
||||
"Clock synchronized via SNTP before attempting TLS/HTTPS handshakes.",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default function DiagnosticoPage() {
|
||||
const pathname = usePathname();
|
||||
const isEn = pathname?.startsWith("/en");
|
||||
const { categoriasDiagnostico, sintomasRapidos, errosCatalogo, regrasDecodificadorLog } = isEn ? diagnosticoEn : diagnosticoPt;
|
||||
const exemplosLog = isEn ? EXEMPLOS_LOG_EN : EXEMPLOS_LOG_PT;
|
||||
const checklists = isEn ? CHECKLISTS_EN : CHECKLISTS_PT;
|
||||
|
||||
const [termoBusca, setTermoBusca] = useState("");
|
||||
const [categoriaAtiva, setCategoriaAtiva] = useState("todos");
|
||||
const [sintomaAtivo, setSintomaAtivo] = useState(null);
|
||||
@@ -101,14 +138,25 @@ export default function DiagnosticoPage() {
|
||||
}
|
||||
}
|
||||
|
||||
setResultadoLog({
|
||||
titulo: "Padrão de erro não categorizado automaticamente",
|
||||
tipo: "Desconhecido",
|
||||
explicacao:
|
||||
"Não identificamos uma assinatura clássica de Guru Meditation ou Brownout neste trecho. Verifique se a taxa de baud rate (ex: 115200) está correta e se o cabeçalho 'rst:' ou 'panic' está presente.",
|
||||
acaoRecomendada:
|
||||
"Procure por palavras-chave como 'Guru Meditation', 'rst:', 'LoadProhibited', 'watchdog' ou 'panic' no console serial.",
|
||||
});
|
||||
setResultadoLog(
|
||||
isEn
|
||||
? {
|
||||
titulo: "Error pattern not automatically classified",
|
||||
tipo: "Unknown",
|
||||
explicacao:
|
||||
"We could not identify a classic Guru Meditation or Brownout signature in this snippet. Verify that the baud rate (e.g. 115200) is correct and whether the 'rst:' or 'panic' header is present.",
|
||||
acaoRecomendada:
|
||||
"Look for keywords such as 'Guru Meditation', 'rst:', 'LoadProhibited', 'watchdog', or 'panic' in the serial output.",
|
||||
}
|
||||
: {
|
||||
titulo: "Padrão de erro não categorizado automaticamente",
|
||||
tipo: "Desconhecido",
|
||||
explicacao:
|
||||
"Não identificamos uma assinatura clássica de Guru Meditation ou Brownout neste trecho. Verifique se a taxa de baud rate (ex: 115200) está correta e se o cabeçalho 'rst:' ou 'panic' está presente.",
|
||||
acaoRecomendada:
|
||||
"Procure por palavras-chave como 'Guru Meditation', 'rst:', 'LoadProhibited', 'watchdog' ou 'panic' no console serial.",
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const copiarParaClipboard = (texto, id) => {
|
||||
@@ -134,7 +182,7 @@ export default function DiagnosticoPage() {
|
||||
|
||||
return matchCategoria && matchSintoma && matchBusca;
|
||||
});
|
||||
}, [categoriaAtiva, sintomaAtivo, termoBusca]);
|
||||
}, [categoriaAtiva, sintomaAtivo, termoBusca, errosCatalogo]);
|
||||
|
||||
const temFiltroAtivo =
|
||||
termoBusca.trim() !== "" ||
|
||||
@@ -156,7 +204,6 @@ export default function DiagnosticoPage() {
|
||||
setLinguagemCodigo((prev) => ({ ...prev, [id]: lang }));
|
||||
};
|
||||
|
||||
|
||||
const totalFiltros = (termoBusca.trim() ? 1 : 0) + (categoriaAtiva !== "todos" ? 1 : 0) + (sintomaAtivo ? 1 : 0);
|
||||
|
||||
return (
|
||||
@@ -165,11 +212,16 @@ export default function DiagnosticoPage() {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Diagnóstico" }]}
|
||||
isEn={isEn}
|
||||
trail={[{ label: isEn ? "Diagnostics" : "Diagnóstico" }]}
|
||||
icon={AlertTriangle}
|
||||
label="Depuração de firmware"
|
||||
title="Diagnóstico de falhas do ESP32"
|
||||
lede="Entenda a causa de Brownout, Guru Meditation, Watchdog e Stack Overflow, e aplique a correção de engenharia, não o remendo."
|
||||
label={isEn ? "Firmware Debugging" : "Depuração de firmware"}
|
||||
title={isEn ? "ESP32 Diagnostics and Crash Decoder" : "Diagnóstico de falhas do ESP32"}
|
||||
lede={
|
||||
isEn
|
||||
? "Understand the root cause of Brownout, Guru Meditation, Watchdog, and Stack Overflow crashes, and apply engineering solutions instead of workarounds."
|
||||
: "Entenda a causa de Brownout, Guru Meditation, Watchdog e Stack Overflow, e aplique a correção de engenharia, não o remendo."
|
||||
}
|
||||
>
|
||||
<a
|
||||
href="https://cienciaembarcada.com.br/publicacoes/esp32-5-erros-comuns-e-como-resolve-los-profissionalmente/"
|
||||
@@ -177,9 +229,9 @@ export default function DiagnosticoPage() {
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex min-h-11 items-center gap-1.5 text-sm font-medium text-accent hover:text-accent-strong"
|
||||
>
|
||||
Baseado no artigo do Ciência Embarcada
|
||||
{isEn ? "Based on article by Ciência Embarcada" : "Baseado no artigo do Ciência Embarcada"}
|
||||
<ExternalLink className="h-4 w-4" aria-hidden="true" />
|
||||
<span className="sr-only"> (abre em nova aba)</span>
|
||||
<span className="sr-only"> {isEn ? "(opens in a new tab)" : "(abre em nova aba)"}</span>
|
||||
</a>
|
||||
</PageHero>
|
||||
|
||||
@@ -187,12 +239,16 @@ export default function DiagnosticoPage() {
|
||||
<div className="panel p-5 sm:p-8">
|
||||
<div className="flex flex-col justify-between gap-4 md:flex-row md:items-end">
|
||||
<div className="max-w-xl">
|
||||
<h2 id="decodificador-titulo" className="section-title">Cole o log e veja a causa</h2>
|
||||
<p className="mt-2 text-sm text-muted">Copie o trecho do monitor serial. O diagnóstico aparece na hora.</p>
|
||||
<h2 id="decodificador-titulo" className="section-title">
|
||||
{isEn ? "Paste the log to see the cause" : "Cole o log e veja a causa"}
|
||||
</h2>
|
||||
<p className="mt-2 text-sm text-muted">
|
||||
{isEn ? "Copy the serial monitor output snippet. Diagnostics appear instantly." : "Copie o trecho do monitor serial. O diagnóstico aparece na hora."}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<span className="text-sm text-muted">Testar com</span>
|
||||
{EXEMPLOS_LOG.map(([rotulo, texto]) => (
|
||||
<span className="text-sm text-muted">{isEn ? "Test with" : "Testar com"}</span>
|
||||
{exemplosLog.map(([rotulo, texto]) => (
|
||||
<button key={rotulo} type="button" onClick={() => analisarLog(texto)} className="chip-btn">
|
||||
{rotulo}
|
||||
</button>
|
||||
@@ -201,20 +257,22 @@ export default function DiagnosticoPage() {
|
||||
</div>
|
||||
|
||||
<div className="relative mt-5">
|
||||
<label htmlFor="log-serial" className="sr-only">Log do monitor serial</label>
|
||||
<label htmlFor="log-serial" className="sr-only">
|
||||
{isEn ? "Serial monitor log" : "Log do monitor serial"}
|
||||
</label>
|
||||
<textarea
|
||||
id="log-serial"
|
||||
rows={4}
|
||||
value={logInput}
|
||||
onChange={(e) => analisarLog(e.target.value)}
|
||||
placeholder="Cole o log do monitor serial aqui"
|
||||
placeholder={isEn ? "Paste serial monitor log here" : "Cole o log do monitor serial aqui"}
|
||||
spellCheck={false}
|
||||
className="code-panel field !min-h-32 w-full resize-y !rounded-xl !border-white/10 !bg-[var(--code-bg)] p-4 font-mono text-sm !text-[#e9eef4] placeholder:!text-[#a6afbd]"
|
||||
/>
|
||||
{logInput && (
|
||||
<button type="button" onClick={() => analisarLog("")} className="absolute right-3 top-3 inline-flex min-h-11 items-center gap-1 rounded-full border border-white/15 px-3 text-xs font-medium text-[#e9eef4] hover:bg-white/10">
|
||||
<X className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
Limpar
|
||||
{isEn ? "Clear" : "Limpar"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -228,8 +286,8 @@ export default function DiagnosticoPage() {
|
||||
<h3 className="font-semibold text-ink">{resultadoLog.titulo}</h3>
|
||||
<span className="chip">{resultadoLog.tipo}</span>
|
||||
</div>
|
||||
<p><strong className="font-semibold text-ink">Causa provável:</strong> {resultadoLog.explicacao}</p>
|
||||
<p><strong className="font-semibold text-ink">O que fazer:</strong> {resultadoLog.acaoRecomendada}</p>
|
||||
<p><strong className="font-semibold text-ink">{isEn ? "Likely cause:" : "Causa provável:"}</strong> {resultadoLog.explicacao}</p>
|
||||
<p><strong className="font-semibold text-ink">{isEn ? "What to do:" : "O que fazer:"}</strong> {resultadoLog.acaoRecomendada}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -238,11 +296,15 @@ export default function DiagnosticoPage() {
|
||||
</section>
|
||||
|
||||
<section className="shell section pt-12 sm:pt-14" aria-labelledby="catalogo-titulo">
|
||||
<h2 id="catalogo-titulo" className="section-title">Catálogo de falhas</h2>
|
||||
<h2 id="catalogo-titulo" className="section-title">
|
||||
{isEn ? "Fault catalog" : "Catálogo de falhas"}
|
||||
</h2>
|
||||
|
||||
<div className="panel mt-6 p-5 sm:p-6">
|
||||
<div className="relative">
|
||||
<label htmlFor="busca-erro" className="sr-only">Buscar por erro, sintoma ou mensagem serial</label>
|
||||
<label htmlFor="busca-erro" className="sr-only">
|
||||
{isEn ? "Search by error, symptom, or serial message" : "Buscar por erro, sintoma ou mensagem serial"}
|
||||
</label>
|
||||
<Search className="pointer-events-none absolute left-4 top-1/2 h-5 w-5 -translate-y-1/2 text-muted" aria-hidden="true" />
|
||||
<input
|
||||
id="busca-erro"
|
||||
@@ -250,14 +312,14 @@ export default function DiagnosticoPage() {
|
||||
type="search"
|
||||
value={termoBusca}
|
||||
onChange={(e) => setTermoBusca(e.target.value)}
|
||||
placeholder="Buscar erro, sintoma ou mensagem"
|
||||
placeholder={isEn ? "Search error, symptom, or message" : "Buscar erro, sintoma ou mensagem"}
|
||||
autoComplete="off"
|
||||
className="field pl-12 pr-4 text-base"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mt-5">
|
||||
<h3 className="text-sm font-semibold text-ink">Sintoma</h3>
|
||||
<h3 className="text-sm font-semibold text-ink">{isEn ? "Symptom" : "Sintoma"}</h3>
|
||||
<div className="mt-3 flex flex-wrap gap-2">
|
||||
{sintomasRapidos.map((sintoma) => (
|
||||
<button key={sintoma.id} type="button" onClick={() => setSintomaAtivo(sintomaAtivo === sintoma.id ? null : sintoma.id)} aria-pressed={sintomaAtivo === sintoma.id} className="chip-btn">
|
||||
@@ -268,11 +330,11 @@ export default function DiagnosticoPage() {
|
||||
</div>
|
||||
|
||||
<div className="mt-5 border-t border-line pt-5">
|
||||
<h3 className="text-sm font-semibold text-ink">Área</h3>
|
||||
<h3 className="text-sm font-semibold text-ink">{isEn ? "Area" : "Área"}</h3>
|
||||
<div className="mt-3 flex flex-wrap gap-2">
|
||||
<button type="button" onClick={() => setCategoriaAtiva("todos")} aria-pressed={categoriaAtiva === "todos"} className="chip-btn">
|
||||
<LayoutGrid className="h-4 w-4" aria-hidden="true" />
|
||||
Todas
|
||||
{isEn ? "All" : "Todas"}
|
||||
<span className="tabular-nums opacity-80">{errosCatalogo.length}</span>
|
||||
</button>
|
||||
{categoriasDiagnostico.map((cat) => {
|
||||
@@ -292,13 +354,13 @@ export default function DiagnosticoPage() {
|
||||
|
||||
<div className="mt-6 flex flex-wrap items-center justify-between gap-3">
|
||||
<p role="status" aria-live="polite" className="text-sm font-semibold text-ink">
|
||||
{errosFiltrados.length} {errosFiltrados.length === 1 ? "falha" : "falhas"}
|
||||
{totalFiltros > 0 && <span className="font-normal text-muted"> com os filtros atuais</span>}
|
||||
{errosFiltrados.length} {errosFiltrados.length === 1 ? (isEn ? "fault" : "falha") : (isEn ? "faults" : "falhas")}
|
||||
{totalFiltros > 0 && <span className="font-normal text-muted">{isEn ? " with current filters" : " com os filtros atuais"}</span>}
|
||||
</p>
|
||||
{temFiltroAtivo && (
|
||||
<button type="button" onClick={limparTodosFiltros} className="inline-flex min-h-11 items-center gap-1.5 text-sm font-medium text-accent hover:text-accent-strong">
|
||||
<RotateCcw className="h-4 w-4" aria-hidden="true" />
|
||||
Redefinir filtros
|
||||
{isEn ? "Reset filters" : "Redefinir filtros"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -307,16 +369,22 @@ export default function DiagnosticoPage() {
|
||||
{errosFiltrados.length === 0 ? (
|
||||
<div className="card px-6 py-14 text-center">
|
||||
<HelpCircle className="mx-auto h-10 w-10 text-muted" aria-hidden="true" />
|
||||
<h3 className="mt-4 font-display text-xl font-semibold text-ink">Nenhuma falha com esses filtros</h3>
|
||||
<p className="mx-auto mt-2 max-w-md text-sm text-muted">Busque por um termo mais geral ou remova o sintoma e a área selecionados.</p>
|
||||
<button type="button" onClick={limparTodosFiltros} className="btn btn-primary mt-6">Limpar filtros</button>
|
||||
<h3 className="mt-4 font-display text-xl font-semibold text-ink">
|
||||
{isEn ? "No faults matching these filters" : "Nenhuma falha com esses filtros"}
|
||||
</h3>
|
||||
<p className="mx-auto mt-2 max-w-md text-sm text-muted">
|
||||
{isEn ? "Search for a more general term or remove selected symptom and area." : "Busque por um termo mais geral ou remova o sintoma e a área selecionados."}
|
||||
</p>
|
||||
<button type="button" onClick={limparTodosFiltros} className="btn btn-primary mt-6">
|
||||
{isEn ? "Clear filters" : "Limpar filtros"}
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
errosFiltrados.map((erro) => {
|
||||
const estaAberto = cardAberto === erro.id;
|
||||
const lang = linguagemCodigo[erro.id] || "arduino";
|
||||
const codigoAtual =
|
||||
lang === "arduino" ? erro.codigoArduino : lang === "espidf" ? erro.codigoEspIdf : erro.codigoMicroPython || "# Exemplo não aplicável";
|
||||
lang === "arduino" ? erro.codigoArduino : lang === "espidf" ? erro.codigoEspIdf : erro.codigoMicroPython || (isEn ? "# Example not applicable" : "# Exemplo não aplicável");
|
||||
const catInfo = categoriasDiagnostico.find((c) => c.id === erro.categoria);
|
||||
const IconeCat = ICONES[catInfo?.icone] ?? AlertTriangle;
|
||||
|
||||
@@ -336,7 +404,13 @@ export default function DiagnosticoPage() {
|
||||
<IconeCat className="h-3.5 w-3.5 text-accent" aria-hidden="true" />
|
||||
{catInfo?.nome}
|
||||
</span>
|
||||
<span className={`chip ${GRAVIDADE[erro.gravidade] ?? "text-accent"}`}>Gravidade {erro.gravidade.toLowerCase()}</span>
|
||||
<span className={`chip ${GRAVIDADE[erro.gravidade] ?? "text-accent"}`}>
|
||||
{isEn ? (
|
||||
<>Severity: {erro.gravidade.toLowerCase()}</>
|
||||
) : (
|
||||
<>Gravidade {erro.gravidade.toLowerCase()}</>
|
||||
)}
|
||||
</span>
|
||||
</span>
|
||||
<span className="mt-3 block font-display text-xl font-semibold tracking-[-0.03em] text-ink">{erro.titulo}</span>
|
||||
<span className="mt-1.5 block text-sm font-normal leading-relaxed text-muted">{erro.resumo}</span>
|
||||
@@ -353,11 +427,11 @@ export default function DiagnosticoPage() {
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<h4 className="flex items-center gap-2 text-sm font-semibold text-ink">
|
||||
<Terminal className="h-4 w-4 text-accent" aria-hidden="true" />
|
||||
Como aparece no monitor serial
|
||||
{isEn ? "How it appears in serial monitor" : "Como aparece no monitor serial"}
|
||||
</h4>
|
||||
<button type="button" onClick={() => copiarParaClipboard(erro.logSerial, `log-${erro.id}`)} className="inline-flex min-h-11 items-center gap-1.5 text-sm font-medium text-accent hover:text-accent-strong">
|
||||
{copiadoId === `log-${erro.id}` ? <Check className="h-4 w-4 text-ok" aria-hidden="true" /> : <Copy className="h-4 w-4" aria-hidden="true" />}
|
||||
{copiadoId === `log-${erro.id}` ? "Copiado" : "Copiar log"}
|
||||
{copiadoId === `log-${erro.id}` ? (isEn ? "Copied" : "Copiado") : (isEn ? "Copy log" : "Copiar log")}
|
||||
</button>
|
||||
</div>
|
||||
<div className="code-panel mt-1">
|
||||
@@ -368,7 +442,7 @@ export default function DiagnosticoPage() {
|
||||
<div>
|
||||
<h4 className="flex items-center gap-2 text-sm font-semibold text-ink">
|
||||
<Cpu className="h-4 w-4 text-accent" aria-hidden="true" />
|
||||
Causa raiz
|
||||
{isEn ? "Root cause" : "Causa raiz"}
|
||||
</h4>
|
||||
<p className="callout mt-2">{erro.causaRaiz}</p>
|
||||
</div>
|
||||
@@ -377,17 +451,17 @@ export default function DiagnosticoPage() {
|
||||
<div className="callout callout-danger">
|
||||
<p className="flex items-center gap-2 font-semibold text-ink">
|
||||
<XCircle className="h-4 w-4 shrink-0 text-danger" aria-hidden="true" />
|
||||
O remendo comum
|
||||
{isEn ? "The common workaround" : "O remendo comum"}
|
||||
</p>
|
||||
<p className="mt-2 font-medium text-ink">{erro.gambiarra.titulo}</p>
|
||||
<p className="mt-1">{erro.gambiarra.descricao}</p>
|
||||
<p className="mt-2"><strong className="font-semibold text-danger">Consequência:</strong> {erro.gambiarra.consequencia}</p>
|
||||
<p className="mt-2"><strong className="font-semibold text-danger">{isEn ? "Consequence:" : "Consequência:"}</strong> {erro.gambiarra.consequencia}</p>
|
||||
</div>
|
||||
|
||||
<div className="callout callout-ok">
|
||||
<p className="flex items-center gap-2 font-semibold text-ink">
|
||||
<CheckCircle2 className="h-4 w-4 shrink-0 text-ok" aria-hidden="true" />
|
||||
A solução de engenharia
|
||||
{isEn ? "The engineering solution" : "A solução de engenharia"}
|
||||
</p>
|
||||
<p className="mt-2 font-medium text-ink">{erro.solucaoEngenharia.titulo}</p>
|
||||
<ul className="mt-2 space-y-1.5">
|
||||
@@ -403,7 +477,7 @@ export default function DiagnosticoPage() {
|
||||
|
||||
<div>
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<div role="group" aria-label="Linguagem do exemplo" className="flex flex-wrap gap-2">
|
||||
<div role="group" aria-label={isEn ? "Example language" : "Linguagem do exemplo"} className="flex flex-wrap gap-2">
|
||||
{[
|
||||
["arduino", "Arduino C++"],
|
||||
["espidf", "ESP-IDF (C)"],
|
||||
@@ -416,7 +490,7 @@ export default function DiagnosticoPage() {
|
||||
</div>
|
||||
<button type="button" onClick={() => copiarParaClipboard(codigoAtual, `code-${erro.id}`)} className="inline-flex min-h-11 items-center gap-1.5 text-sm font-medium text-accent hover:text-accent-strong">
|
||||
{copiadoId === `code-${erro.id}` ? <Check className="h-4 w-4 text-ok" aria-hidden="true" /> : <Copy className="h-4 w-4" aria-hidden="true" />}
|
||||
{copiadoId === `code-${erro.id}` ? "Copiado" : "Copiar código"}
|
||||
{copiadoId === `code-${erro.id}` ? (isEn ? "Copied" : "Copiado") : (isEn ? "Copy code" : "Copiar código")}
|
||||
</button>
|
||||
</div>
|
||||
<div className="code-panel mt-3">
|
||||
@@ -426,7 +500,7 @@ export default function DiagnosticoPage() {
|
||||
|
||||
<div className="callout callout-warn flex items-start gap-3">
|
||||
<Wrench className="mt-0.5 h-4 w-4 shrink-0 text-gold" aria-hidden="true" />
|
||||
<p><strong className="font-semibold text-ink">Dica de engenharia:</strong> {erro.dicaPro}</p>
|
||||
<p><strong className="font-semibold text-ink">{isEn ? "Engineering tip:" : "Dica de engenharia:"}</strong> {erro.dicaPro}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -438,10 +512,14 @@ export default function DiagnosticoPage() {
|
||||
</section>
|
||||
|
||||
<section className="shell pb-20 md:pb-28" aria-labelledby="checklist-titulo">
|
||||
<h2 id="checklist-titulo" className="section-title">Checklist antes de ir para campo</h2>
|
||||
<p className="mt-3 max-w-2xl text-base text-muted">Itens essenciais para validar no hardware e no firmware antes de entregar o produto.</p>
|
||||
<h2 id="checklist-titulo" className="section-title">
|
||||
{isEn ? "Pre-deployment checklist" : "Checklist antes de ir para campo"}
|
||||
</h2>
|
||||
<p className="mt-3 max-w-2xl text-base text-muted">
|
||||
{isEn ? "Essential items to validate on hardware and firmware before shipping a product." : "Itens essenciais para validar no hardware e no firmware antes de entregar o produto."}
|
||||
</p>
|
||||
<div className="mt-8 grid gap-4 md:grid-cols-2">
|
||||
{CHECKLISTS.map(({ icon: Icon, titulo, itens }) => (
|
||||
{checklists.map(({ icon: Icon, titulo, itens }) => (
|
||||
<div key={titulo} className="card p-5 sm:p-7">
|
||||
<h3 className="flex items-center gap-3 font-display text-xl font-semibold tracking-[-0.03em] text-ink">
|
||||
<span className="grid h-9 w-9 place-items-center rounded-full bg-accent-soft text-accent">
|
||||
@@ -5,11 +5,16 @@ import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import { notFound } from "next/navigation";
|
||||
import CodeExample from "@/components/CodeExample";
|
||||
import frameworksData from "@/public/frameworks.json";
|
||||
import frameworksDataPt from "@/public/frameworks.json";
|
||||
import frameworksDataEn from "@/data/en/frameworks.json";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
import { ArrowRight, ArrowUpRight, BookOpen, Box, Check, Code, Layers } from "lucide-react";
|
||||
|
||||
export default async function FrameworkDetail({ params }) {
|
||||
const { key } = await params;
|
||||
const { locale, key } = await params;
|
||||
const isEn = locale === "en";
|
||||
const currentLocale = isEn ? "en" : "pt";
|
||||
const frameworksData = isEn ? frameworksDataEn : frameworksDataPt;
|
||||
const framework = frameworksData[key];
|
||||
|
||||
if (!framework) {
|
||||
@@ -25,15 +30,15 @@ export default async function FrameworkDetail({ params }) {
|
||||
{/* Ficha técnica do framework e trilha de navegação para o Google */}
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.framework(key, framework)) }}
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.framework(key, framework, currentLocale)) }}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Frameworks", caminho: "/frameworks" },
|
||||
{ nome: framework.nome, caminho: `/frameworks/${encodeURIComponent(key)}` },
|
||||
{ nome: isEn ? "Home" : "Início", caminho: isEn ? "/en" : "/" },
|
||||
{ nome: isEn ? "Frameworks" : "Frameworks", caminho: getLocalizedHref("/frameworks", currentLocale) },
|
||||
{ nome: framework.nome, caminho: getLocalizedHref(`/frameworks/${encodeURIComponent(key)}`, currentLocale) },
|
||||
])),
|
||||
}}
|
||||
/>
|
||||
@@ -42,7 +47,8 @@ export default async function FrameworkDetail({ params }) {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Frameworks e SDKs", href: "/frameworks" }, { label: framework.nome }]}
|
||||
isEn={isEn}
|
||||
trail={[{ label: isEn ? "Frameworks & SDKs" : "Frameworks e SDKs", href: getLocalizedHref("/frameworks", currentLocale) }, { label: framework.nome }]}
|
||||
icon={Layers}
|
||||
label={framework.tipo}
|
||||
title={framework.nome}
|
||||
@@ -51,40 +57,42 @@ export default async function FrameworkDetail({ params }) {
|
||||
{framework.documentacao && (
|
||||
<a href={framework.documentacao} target="_blank" rel="noopener noreferrer" className="btn btn-primary">
|
||||
<BookOpen className="h-4 w-4" aria-hidden="true" />
|
||||
Documentação oficial
|
||||
{isEn ? "Official documentation" : "Documentação oficial"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
)}
|
||||
{framework.repositorio && (
|
||||
<a href={framework.repositorio} target="_blank" rel="noopener noreferrer" className="btn btn-ghost">
|
||||
<Code className="h-4 w-4" aria-hidden="true" />
|
||||
Repositório no GitHub
|
||||
{isEn ? "GitHub repository" : "Repositório no GitHub"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
)}
|
||||
</PageHero>
|
||||
|
||||
<section className="shell mt-10" aria-label="Resumo">
|
||||
<section className="shell mt-10" aria-label={isEn ? "Summary" : "Resumo"}>
|
||||
<dl className="grid gap-3 md:grid-cols-3">
|
||||
<div className="tile">
|
||||
<dt className="text-xs font-medium text-muted">Linguagem</dt>
|
||||
<dt className="text-xs font-medium text-muted">{isEn ? "Language" : "Linguagem"}</dt>
|
||||
<dd className="mt-1 font-display text-2xl font-semibold tracking-[-0.03em] text-ink">{framework.linguagem}</dd>
|
||||
<dd className="mt-0.5 text-xs text-muted">{framework.nome_completo}</dd>
|
||||
</div>
|
||||
<div className="tile">
|
||||
<dt className="text-xs font-medium text-muted">Categoria</dt>
|
||||
<dt className="text-xs font-medium text-muted">{isEn ? "Category" : "Categoria"}</dt>
|
||||
<dd className="mt-1 font-display text-2xl font-semibold tracking-[-0.03em] text-ink">{framework.tipo}</dd>
|
||||
</div>
|
||||
<div className="tile">
|
||||
<dt className="text-xs font-medium text-muted">Objetivo principal</dt>
|
||||
<dt className="text-xs font-medium text-muted">{isEn ? "Main purpose" : "Objetivo principal"}</dt>
|
||||
<dd className="mt-1 text-sm font-medium leading-relaxed text-ink">{framework.funcao_principal}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section className="shell mt-12 grid gap-5 lg:grid-cols-2" aria-label="Recursos e aplicações">
|
||||
<section className="shell mt-12 grid gap-5 lg:grid-cols-2" aria-label={isEn ? "Features and applications" : "Recursos e aplicações"}>
|
||||
<div className="card p-5 sm:p-7">
|
||||
<h2 className="font-display text-xl font-semibold tracking-[-0.03em] text-ink">Recursos de destaque</h2>
|
||||
<h2 className="font-display text-xl font-semibold tracking-[-0.03em] text-ink">
|
||||
{isEn ? "Key features" : "Recursos de destaque"}
|
||||
</h2>
|
||||
<ul className="mt-5 space-y-3">
|
||||
{features.map((feature) => (
|
||||
<li key={feature} className="flex items-start gap-3 text-sm leading-relaxed text-ink-soft">
|
||||
@@ -96,7 +104,9 @@ export default async function FrameworkDetail({ params }) {
|
||||
</div>
|
||||
|
||||
<div className="card p-5 sm:p-7">
|
||||
<h2 className="font-display text-xl font-semibold tracking-[-0.03em] text-ink">Quando usar</h2>
|
||||
<h2 className="font-display text-xl font-semibold tracking-[-0.03em] text-ink">
|
||||
{isEn ? "When to use" : "Quando usar"}
|
||||
</h2>
|
||||
<ul className="mt-5 space-y-2.5">
|
||||
{useCases.map((useCase) => (
|
||||
<li key={useCase} className="tile text-sm font-medium text-ink-soft">
|
||||
@@ -113,17 +123,29 @@ export default async function FrameworkDetail({ params }) {
|
||||
<div className="max-w-2xl">
|
||||
<span className="chip chip-accent">
|
||||
<Box className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
ESP-IDF 4.4 ou superior
|
||||
{isEn ? "ESP-IDF 4.4 or higher" : "ESP-IDF 4.4 ou superior"}
|
||||
</span>
|
||||
<h2 className="section-title mt-4">Módulos com o ESP Component Registry</h2>
|
||||
<h2 className="section-title mt-4">
|
||||
{isEn ? "Modules with the ESP Component Registry" : "Módulos com o ESP Component Registry"}
|
||||
</h2>
|
||||
<p className="mt-3 text-base leading-relaxed text-muted">
|
||||
Nos projetos ESP-IDF v4.4+ e v5.x, as bibliotecas não precisam mais entrar como submódulos Git. Use o{" "}
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code> e o comando{" "}
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf.py add-dependency</code> para baixar drivers de display (LVGL), pilhas industriais (Modbus), RainMaker e mais.
|
||||
{isEn ? (
|
||||
<>
|
||||
In ESP-IDF v4.4+ and v5.x projects, libraries no longer need to be added as Git submodules. Use{" "}
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code> and the command{" "}
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf.py add-dependency</code> to download display drivers (LVGL), industrial stacks (Modbus), RainMaker, and more.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Nos projetos ESP-IDF v4.4+ e v5.x, as bibliotecas não precisam mais entrar como submódulos Git. Use o{" "}
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code> e o comando{" "}
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf.py add-dependency</code> para baixar drivers de display (LVGL), pilhas industriais (Modbus), RainMaker e mais.
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<Link href="/componentes" className="btn btn-primary shrink-0">
|
||||
Explorar componentes
|
||||
<Link href={getLocalizedHref("/componentes", currentLocale)} className="btn btn-primary shrink-0">
|
||||
{isEn ? "Explore components" : "Explorar componentes"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
@@ -137,9 +159,9 @@ export default async function FrameworkDetail({ params }) {
|
||||
)}
|
||||
|
||||
<div className="shell section pt-10">
|
||||
<Link href="/frameworks" className="inline-flex min-h-11 items-center gap-2 text-sm font-medium text-accent hover:text-accent-strong">
|
||||
<Link href={getLocalizedHref("/frameworks", currentLocale)} className="inline-flex min-h-11 items-center gap-2 text-sm font-medium text-accent hover:text-accent-strong">
|
||||
<ArrowRight className="h-4 w-4 rotate-180" aria-hidden="true" />
|
||||
Ver todos os frameworks
|
||||
{isEn ? "View all frameworks" : "Ver todos os frameworks"}
|
||||
</Link>
|
||||
</div>
|
||||
</main>
|
||||
@@ -150,31 +172,43 @@ export default async function FrameworkDetail({ params }) {
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { key } = await params;
|
||||
const { locale, key } = await params;
|
||||
const isEn = locale === "en";
|
||||
const currentLocale = isEn ? "en" : "pt";
|
||||
const frameworksData = isEn ? frameworksDataEn : frameworksDataPt;
|
||||
const framework = frameworksData[key];
|
||||
|
||||
if (!framework) {
|
||||
return { title: "Framework não encontrado", robots: { index: false, follow: false } };
|
||||
return { title: isEn ? "Framework not found" : "Framework não encontrado", robots: { index: false, follow: false } };
|
||||
}
|
||||
|
||||
return {
|
||||
...paginaMeta({
|
||||
titulo: `${framework.nome} para ESP32 · Guia Técnico`,
|
||||
descricao: `${framework.nome_completo}: ${framework.descricao} Guia com exemplos práticos de código e casos de uso.`,
|
||||
titulo: isEn ? `${framework.nome} for ESP32 · Technical Guide` : `${framework.nome} para ESP32 · Guia Técnico`,
|
||||
descricao: isEn
|
||||
? `${framework.nome_completo}: ${framework.descricao} Guide with practical code examples and use cases.`
|
||||
: `${framework.nome_completo}: ${framework.descricao} Guia com exemplos práticos de código e casos de uso.`,
|
||||
caminho: `/frameworks/${encodeURIComponent(key)}`,
|
||||
tipo: "article",
|
||||
keywords: [
|
||||
framework.nome, framework.nome_completo,
|
||||
`${framework.nome} ESP32`, `programar ESP32 com ${framework.nome}`,
|
||||
"ESP32", "framework ESP32",
|
||||
],
|
||||
locale: currentLocale,
|
||||
keywords: isEn
|
||||
? [
|
||||
framework.nome, framework.nome_completo,
|
||||
`${framework.nome} ESP32`, `program ESP32 with ${framework.nome}`,
|
||||
"ESP32", "ESP32 framework",
|
||||
]
|
||||
: [
|
||||
framework.nome, framework.nome_completo,
|
||||
`${framework.nome} ESP32`, `programar ESP32 com ${framework.nome}`,
|
||||
"ESP32", "framework ESP32",
|
||||
],
|
||||
}),
|
||||
other: { "article:section": "Frameworks" },
|
||||
};
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return Object.keys(frameworksData).map((key) => ({
|
||||
return Object.keys(frameworksDataPt).map((key) => ({
|
||||
key: key,
|
||||
}));
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
return {
|
||||
...paginaMeta({
|
||||
titulo: isEn
|
||||
? "ESP32 Frameworks & SDKs: Complete Guide and Comparison"
|
||||
: "Frameworks & SDKs para ESP32: Guia Completo e Comparativo",
|
||||
descricao: isEn
|
||||
? "Complete development guide: ESP-IDF, ESP-RainMaker, ESP-Matter, Rust, ESP-ADF, ESP-SR, ESP-WHO, Arduino, and MicroPython with code examples."
|
||||
: "Guia completo de desenvolvimento: ESP-IDF, ESP-RainMaker, ESP-Matter, Rust, ESP-ADF, ESP-SR, ESP-WHO, Arduino e MicroPython com exemplos de código.",
|
||||
caminho: "/frameworks",
|
||||
locale: isEn ? "en" : "pt",
|
||||
keywords: isEn
|
||||
? [
|
||||
"ESP-IDF",
|
||||
"ESP-RainMaker",
|
||||
"ESP-Matter",
|
||||
"Rust ESP32",
|
||||
"ESP-SR",
|
||||
"ESP-ADF",
|
||||
"ESP-IoT-Solution",
|
||||
"Arduino ESP32",
|
||||
"MicroPython ESP32",
|
||||
"frameworks ESP32",
|
||||
"program ESP32",
|
||||
]
|
||||
: [
|
||||
"ESP-IDF",
|
||||
"ESP-RainMaker",
|
||||
"ESP-Matter",
|
||||
"Rust ESP32",
|
||||
"ESP-SR",
|
||||
"ESP-ADF",
|
||||
"ESP-IoT-Solution",
|
||||
"Arduino ESP32",
|
||||
"MicroPython ESP32",
|
||||
"frameworks ESP32",
|
||||
"programar ESP32",
|
||||
],
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
export default async function FrameworksLayout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: isEn ? "Home" : "Início", caminho: isEn ? "/en" : "/" },
|
||||
{ nome: "Frameworks", caminho: isEn ? "/en/frameworks" : "/frameworks" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -3,10 +3,13 @@ import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import SectionHead from "@/components/SectionHead";
|
||||
import Link from "next/link";
|
||||
import frameworksData from "@/public/frameworks.json";
|
||||
import frameworksDataPt from "@/public/frameworks.json";
|
||||
import frameworksDataEn from "@/data/en/frameworks.json";
|
||||
import { paginaMeta } from "@/lib/seo";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
import { ArrowRight, ArrowUpRight, Box, Brain, Cloud, GraduationCap, Layers, Mic, Music, Sparkles } from "lucide-react";
|
||||
|
||||
const GUIAS = [
|
||||
const GUIAS_PT = [
|
||||
{
|
||||
icon: GraduationCap,
|
||||
titulo: "Estou começando",
|
||||
@@ -39,8 +42,46 @@ const GUIAS = [
|
||||
},
|
||||
];
|
||||
|
||||
export default function Frameworks() {
|
||||
const GUIAS_EN = [
|
||||
{
|
||||
icon: GraduationCap,
|
||||
titulo: "Getting Started",
|
||||
texto: "Arduino or MicroPython are the fastest routes to test sensors and APIs. For production, go with ESP-IDF or Rust.",
|
||||
links: [
|
||||
["Arduino", "/frameworks/Arduino"],
|
||||
["MicroPython", "/frameworks/MicroPython"],
|
||||
["Rust", "/frameworks/Rust-ESP"],
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Cloud,
|
||||
titulo: "Cloud and Connected Home",
|
||||
texto: "ESP-Matter for interoperability, ESP-RainMaker for ready-made cloud, and Zigbee for low-power local mesh networks.",
|
||||
links: [
|
||||
["RainMaker", "/frameworks/ESP-RainMaker"],
|
||||
["Matter", "/frameworks/ESP-Matter"],
|
||||
["Zigbee", "/frameworks/ESP-Zigbee-SDK"],
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Sparkles,
|
||||
titulo: "Audio, Voice and AI",
|
||||
texto: "ESP-ADF for audio processing, ESP-SR for offline speech recognition, and ESP-NN for accelerating TinyML.",
|
||||
links: [
|
||||
["Audio", "/frameworks/ESP-ADF", Music],
|
||||
["Voice", "/frameworks/ESP-SR", Mic],
|
||||
["AI", "/frameworks/ESP-NN", Brain],
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default async function Frameworks({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const currentLocale = isEn ? "en" : "pt";
|
||||
const frameworksData = isEn ? frameworksDataEn : frameworksDataPt;
|
||||
const frameworks = Object.entries(frameworksData);
|
||||
const guias = isEn ? GUIAS_EN : GUIAS_PT;
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
@@ -48,16 +89,21 @@ export default function Frameworks() {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Frameworks e SDKs" }]}
|
||||
isEn={isEn}
|
||||
trail={[{ label: isEn ? "Frameworks & SDKs" : "Frameworks e SDKs" }]}
|
||||
icon={Layers}
|
||||
label={`${frameworks.length} frameworks e SDKs`}
|
||||
title="Frameworks e SDKs do ESP32"
|
||||
lede="Do C/C++ nativo com FreeRTOS ao Rust, passando por nuvem IoT, reconhecimento de voz, áudio e Matter. Escolha pelo que você quer construir."
|
||||
label={isEn ? `${frameworks.length} frameworks and SDKs` : `${frameworks.length} frameworks e SDKs`}
|
||||
title={isEn ? "ESP32 Frameworks and SDKs" : "Frameworks e SDKs do ESP32"}
|
||||
lede={
|
||||
isEn
|
||||
? "From native C/C++ with FreeRTOS to Rust, IoT cloud, speech recognition, audio, and Matter. Choose by what you want to build."
|
||||
: "Do C/C++ nativo com FreeRTOS ao Rust, passando por nuvem IoT, reconhecimento de voz, áudio e Matter. Escolha pelo que você quer construir."
|
||||
}
|
||||
/>
|
||||
|
||||
<section className="shell pt-10 sm:pt-12" aria-label="Por onde começar">
|
||||
<section className="shell pt-10 sm:pt-12" aria-label={isEn ? "Where to begin" : "Por onde começar"}>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
{GUIAS.map(({ icon: Icon, titulo, texto, links }) => (
|
||||
{guias.map(({ icon: Icon, titulo, texto, links }) => (
|
||||
<div key={titulo} className="card flex flex-col p-5 sm:p-6">
|
||||
<span className="grid h-10 w-10 place-items-center rounded-full bg-accent-soft text-accent">
|
||||
<Icon className="h-5 w-5" aria-hidden="true" />
|
||||
@@ -67,7 +113,7 @@ export default function Frameworks() {
|
||||
<ul className="mt-5 flex flex-wrap gap-2 border-t border-line pt-4">
|
||||
{links.map(([rotulo, href, Extra]) => (
|
||||
<li key={rotulo}>
|
||||
<Link href={href} className="chip-btn">
|
||||
<Link href={getLocalizedHref(href, currentLocale)} className="chip-btn">
|
||||
{Extra && <Extra className="h-4 w-4" aria-hidden="true" />}
|
||||
{rotulo}
|
||||
</Link>
|
||||
@@ -84,27 +130,41 @@ export default function Frameworks() {
|
||||
<div className="max-w-2xl">
|
||||
<span className="chip chip-accent">
|
||||
<Box className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
Arquitetura modular
|
||||
{isEn ? "Modular architecture" : "Arquitetura modular"}
|
||||
</span>
|
||||
<h2 className="section-title mt-4">ESP Component Registry</h2>
|
||||
<p className="mt-3 text-base leading-relaxed text-muted">
|
||||
Instale drivers de display (LVGL), pilhas industriais (Modbus), recursos de nuvem e pacotes de placa
|
||||
(BSPs) com uma linha no manifesto <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code>.
|
||||
{isEn ? (
|
||||
<>
|
||||
Install display drivers (LVGL), industrial stacks (Modbus), cloud integrations, and board support packages
|
||||
(BSPs) with a single line in your <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code> manifest.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Instale drivers de display (LVGL), pilhas industriais (Modbus), recursos de nuvem e pacotes de placa
|
||||
(BSPs) com uma linha no manifesto <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code>.
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<Link href="/componentes" className="btn btn-primary shrink-0">
|
||||
Explorar componentes
|
||||
<Link href={getLocalizedHref("/componentes", currentLocale)} className="btn btn-primary shrink-0">
|
||||
{isEn ? "Explore components" : "Explorar componentes"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="shell section" aria-labelledby="todos-titulo">
|
||||
<SectionHead id="todos-titulo" eyebrow="Todos" title="Todos os frameworks" lede="Cada ficha traz recursos, aplicações ideais, exemplo de código e links oficiais." />
|
||||
<SectionHead
|
||||
id="todos-titulo"
|
||||
eyebrow={isEn ? "All" : "Todos"}
|
||||
title={isEn ? "All frameworks" : "Todos os frameworks"}
|
||||
lede={isEn ? "Each page provides features, ideal use cases, code examples, and official links." : "Cada ficha traz recursos, aplicações ideais, exemplo de código e links oficiais."}
|
||||
/>
|
||||
|
||||
<div className="mt-8 grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{frameworks.map(([key, framework]) => (
|
||||
<Link key={key} href={`/frameworks/${encodeURIComponent(key)}`} className="card card-interactive group flex flex-col p-5 sm:p-6">
|
||||
<Link key={key} href={getLocalizedHref(`/frameworks/${encodeURIComponent(key)}`, currentLocale)} className="card card-interactive group flex flex-col p-5 sm:p-6">
|
||||
<div className="flex flex-wrap items-start justify-between gap-2">
|
||||
<h3 className="font-display text-xl font-semibold tracking-[-0.03em] text-ink">{framework.nome}</h3>
|
||||
<span className="chip max-w-full">{framework.linguagem}</span>
|
||||
@@ -121,7 +181,7 @@ export default function Frameworks() {
|
||||
</ul>
|
||||
|
||||
<span className="mt-5 inline-flex items-center gap-1 border-t border-line pt-4 text-sm font-medium text-accent">
|
||||
Ver detalhes e exemplo
|
||||
{isEn ? "View details and example" : "Ver detalhes e exemplo"}
|
||||
<ArrowUpRight className="h-4 w-4 transition-transform group-hover:-translate-y-0.5 group-hover:translate-x-0.5" aria-hidden="true" />
|
||||
</span>
|
||||
</Link>
|
||||
@@ -0,0 +1,81 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
import { categoriasGlossario as categoriasGlossarioPt } from "@/lib/glossarioData";
|
||||
import { categoriasGlossario as categoriasGlossarioEn } from "@/lib/data/en/glossario.js";
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
return paginaMeta({
|
||||
titulo: isEn
|
||||
? "ESP32 Technical Glossary: Terms and Concepts"
|
||||
: "Glossário Técnico do ESP32: Termos e Conceitos",
|
||||
descricao: isEn
|
||||
? "Over 50 essential ESP32 concepts explained: GPIO, Strapping Pins, ULP, PSRAM, FreeRTOS, eFuse, Deep Sleep, OTA, Secure Boot, ECDSA, Matter, and Thread."
|
||||
: "Mais de 50 termos e conceitos essenciais do ecossistema ESP32 explicados em português: GPIO, Strapping Pins, ULP, PSRAM, FreeRTOS, eFuse, Deep Sleep, OTA, Secure Boot, ECDSA, Matter e Thread.",
|
||||
caminho: "/glossario",
|
||||
locale,
|
||||
keywords: isEn
|
||||
? [
|
||||
"ESP32 glossary",
|
||||
"what is GPIO",
|
||||
"what are strapping pins",
|
||||
"what is ESP32 ULP",
|
||||
"what is ESP32 PSRAM",
|
||||
"microcontroller technical terms",
|
||||
"ESP32 hardware concepts",
|
||||
]
|
||||
: [
|
||||
"glossário ESP32",
|
||||
"o que é GPIO",
|
||||
"o que é strapping pins",
|
||||
"o que é ULP ESP32",
|
||||
"o que é PSRAM ESP32",
|
||||
"termos técnicos microcontrolador",
|
||||
"conceitos ESP32 português",
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export default async function GlossarioLayout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const categorias = isEn ? categoriasGlossarioEn : categoriasGlossarioPt;
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.glossario(categorias, locale)),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: isEn ? "Home" : "Início", caminho: isEn ? "/en" : "/" },
|
||||
{ nome: isEn ? "Technical Glossary" : "Glossário Técnico", caminho: isEn ? "/en/glossary" : "/glossario" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.aplicacaoWeb({
|
||||
nome: isEn ? "ESP32 Technical Glossary" : "Glossário Técnico do ESP32",
|
||||
descricao: isEn
|
||||
? "Encyclopedia of hardware and software technical terms for the ESP32 ecosystem."
|
||||
: "Enciclopédia de termos técnicos e conceitos de hardware e software do ecossistema ESP32.",
|
||||
caminho: isEn ? "/en/glossary" : "/glossario",
|
||||
locale,
|
||||
})
|
||||
),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useMemo, useRef } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import Link from "next/link";
|
||||
import { categoriasGlossario } from "@/lib/glossarioData";
|
||||
import * as glossarioPt from "@/lib/glossarioData";
|
||||
import * as glossarioEn from "@/lib/data/en/glossario";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
import {
|
||||
ArrowRight,
|
||||
BookOpen,
|
||||
@@ -35,6 +38,11 @@ const ICONES = { Cpu, Database, Wifi, Sliders, Sparkles, BatteryCharging, Code2,
|
||||
const nomeCurto = (nome) => nome.split(/,| &/)[0].trim();
|
||||
|
||||
export default function GlossarioPage() {
|
||||
const pathname = usePathname();
|
||||
const isEn = pathname?.startsWith("/en");
|
||||
const currentLocale = isEn ? "en" : "pt";
|
||||
const { categoriasGlossario } = isEn ? glossarioEn : glossarioPt;
|
||||
|
||||
const [busca, setBusca] = useState("");
|
||||
const [categoriaSelecionada, setCategoriaSelecionada] = useState("todas");
|
||||
const [letraFiltro, setLetraFiltro] = useState(null);
|
||||
@@ -53,7 +61,7 @@ export default function GlossarioPage() {
|
||||
primeiraLetra: t.termo.charAt(0).toUpperCase(),
|
||||
}))
|
||||
),
|
||||
[]
|
||||
[categoriasGlossario]
|
||||
);
|
||||
|
||||
const alfabeto = useMemo(() => {
|
||||
@@ -86,7 +94,8 @@ export default function GlossarioPage() {
|
||||
};
|
||||
|
||||
const copiarLinkTermo = (slug) => {
|
||||
navigator.clipboard.writeText(`${window.location.origin}/glossario#${slug}`);
|
||||
const basePath = getLocalizedHref("/glossario", currentLocale);
|
||||
navigator.clipboard.writeText(`${window.location.origin}${basePath}#${slug}`);
|
||||
setCopiadoSlug(slug);
|
||||
setTimeout(() => setCopiadoSlug(null), 2000);
|
||||
};
|
||||
@@ -99,18 +108,23 @@ export default function GlossarioPage() {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Glossário" }]}
|
||||
isEn={isEn}
|
||||
trail={[{ label: isEn ? "Glossary" : "Glossário" }]}
|
||||
icon={BookOpen}
|
||||
label={`${todosOsTermos.length} termos explicados`}
|
||||
title="Glossário técnico do ESP32"
|
||||
lede="Definições diretas, parâmetros de hardware e um exemplo prático para cada termo do ecossistema, de ADC a Secure Boot."
|
||||
label={isEn ? `${todosOsTermos.length} terms explained` : `${todosOsTermos.length} termos explicados`}
|
||||
title={isEn ? "ESP32 Technical Glossary" : "Glossário técnico do ESP32"}
|
||||
lede={
|
||||
isEn
|
||||
? "Direct definitions, hardware parameters, and practical examples for every ecosystem term, from ADC to Secure Boot."
|
||||
: "Definições diretas, parâmetros de hardware e um exemplo prático para cada termo do ecossistema, de ADC a Secure Boot."
|
||||
}
|
||||
/>
|
||||
|
||||
<section className="shell pt-10 sm:pt-12" aria-label="Busca e filtros">
|
||||
<section className="shell pt-10 sm:pt-12" aria-label={isEn ? "Search and filters" : "Busca e filtros"}>
|
||||
<div className="panel p-5 sm:p-7">
|
||||
<div className="relative">
|
||||
<label htmlFor="busca-glossario" className="sr-only">
|
||||
Buscar termo, sigla ou conceito
|
||||
{isEn ? "Search term, acronym, or concept" : "Buscar termo, sigla ou conceito"}
|
||||
</label>
|
||||
<Search className="pointer-events-none absolute left-4 top-1/2 h-5 w-5 -translate-y-1/2 text-muted" aria-hidden="true" />
|
||||
<input
|
||||
@@ -119,7 +133,7 @@ export default function GlossarioPage() {
|
||||
type="search"
|
||||
value={busca}
|
||||
onChange={(e) => setBusca(e.target.value)}
|
||||
placeholder="Buscar termo, sigla ou conceito"
|
||||
placeholder={isEn ? "Search term, acronym, or concept" : "Buscar termo, sigla ou conceito"}
|
||||
autoComplete="off"
|
||||
className={`field pl-12 text-base ${busca ? "pr-28" : "pr-4"}`}
|
||||
/>
|
||||
@@ -127,20 +141,19 @@ export default function GlossarioPage() {
|
||||
{busca && (
|
||||
<button type="button" onClick={() => { setBusca(""); searchInputRef.current?.focus(); }} className="btn btn-ghost btn-sm">
|
||||
<X className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
Limpar
|
||||
{isEn ? "Clear" : "Limpar"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 flex flex-wrap items-center gap-2">
|
||||
<span className="mr-1 text-sm text-muted">Mais buscados</span>
|
||||
<span className="mr-1 text-sm text-muted">{isEn ? "Popular searches" : "Mais buscados"}</span>
|
||||
{BUSCAS_POPULARES.map((rotulo) => (
|
||||
<button
|
||||
key={rotulo}
|
||||
type="button"
|
||||
onClick={() => setBusca(rotulo)}
|
||||
aria-pressed={busca.toLowerCase() === rotulo.toLowerCase()}
|
||||
onClick={() => { setBusca(rotulo); setCategoriaSelecionada("todas"); setLetraFiltro(null); }}
|
||||
className="chip-btn"
|
||||
>
|
||||
{rotulo}
|
||||
@@ -148,12 +161,17 @@ export default function GlossarioPage() {
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-7 border-t border-line pt-6">
|
||||
<h2 className="text-sm font-semibold text-ink">Categoria</h2>
|
||||
<div className="mt-5 border-t border-line pt-5">
|
||||
<h2 className="text-sm font-semibold text-ink">{isEn ? "Category" : "Categoria"}</h2>
|
||||
<div className="mt-3 flex flex-wrap gap-2">
|
||||
<button type="button" onClick={() => setCategoriaSelecionada("todas")} aria-pressed={categoriaSelecionada === "todas"} className="chip-btn">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setCategoriaSelecionada("todas")}
|
||||
aria-pressed={categoriaSelecionada === "todas"}
|
||||
className="chip-btn"
|
||||
>
|
||||
<LayoutGrid className="h-4 w-4" aria-hidden="true" />
|
||||
Todas
|
||||
{isEn ? "All" : "Todas"}
|
||||
<span className="tabular-nums opacity-80">{todosOsTermos.length}</span>
|
||||
</button>
|
||||
{categoriasGlossario.map((cat) => {
|
||||
@@ -176,10 +194,10 @@ export default function GlossarioPage() {
|
||||
</div>
|
||||
|
||||
<div className="mt-6 border-t border-line pt-6">
|
||||
<h2 className="text-sm font-semibold text-ink">Ordem alfabética</h2>
|
||||
<div className="mt-3 flex flex-wrap gap-1.5" role="group" aria-label="Filtrar pela letra inicial">
|
||||
<h2 className="text-sm font-semibold text-ink">{isEn ? "Alphabetical order" : "Ordem alfabética"}</h2>
|
||||
<div className="mt-3 flex flex-wrap gap-1.5" role="group" aria-label={isEn ? "Filter by first letter" : "Filtrar pela letra inicial"}>
|
||||
<button type="button" onClick={() => setLetraFiltro(null)} aria-pressed={letraFiltro === null} className="chip-btn">
|
||||
Todas
|
||||
{isEn ? "All" : "Todas"}
|
||||
</button>
|
||||
{alfabeto.map(({ letra, temTermos }) => (
|
||||
<button
|
||||
@@ -188,7 +206,7 @@ export default function GlossarioPage() {
|
||||
disabled={!temTermos}
|
||||
onClick={() => setLetraFiltro(letraFiltro === letra ? null : letra)}
|
||||
aria-pressed={letraFiltro === letra}
|
||||
className="chip-btn min-w-11 justify-center px-0 disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-surface"
|
||||
className="chip-btn min-w-[2.25rem] justify-center text-xs"
|
||||
>
|
||||
{letra}
|
||||
</button>
|
||||
@@ -201,13 +219,13 @@ export default function GlossarioPage() {
|
||||
<section className="shell section pt-8 sm:pt-10" aria-labelledby="resultado-titulo">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<h2 id="resultado-titulo" className="text-base font-semibold text-ink" role="status" aria-live="polite">
|
||||
{total} {total === 1 ? "termo" : "termos"}
|
||||
{temFiltroAtivo && <span className="font-normal text-muted"> com os filtros atuais</span>}
|
||||
{total} {total === 1 ? (isEn ? "term" : "termo") : (isEn ? "terms" : "termos")}
|
||||
{temFiltroAtivo && <span className="font-normal text-muted">{isEn ? " with current filters" : " com os filtros atuais"}</span>}
|
||||
</h2>
|
||||
{temFiltroAtivo && (
|
||||
<button type="button" onClick={limparTodosFiltros} className="inline-flex min-h-11 items-center gap-1.5 text-sm font-medium text-accent hover:text-accent-strong">
|
||||
<RotateCcw className="h-4 w-4" aria-hidden="true" />
|
||||
Redefinir filtros
|
||||
{isEn ? "Reset filters" : "Redefinir filtros"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -215,13 +233,17 @@ export default function GlossarioPage() {
|
||||
{total === 0 ? (
|
||||
<div className="card mt-6 px-6 py-14 text-center">
|
||||
<HelpCircle className="mx-auto h-10 w-10 text-muted" aria-hidden="true" />
|
||||
<h3 className="mt-4 font-display text-xl font-semibold text-ink">Nenhum termo encontrado</h3>
|
||||
<h3 className="mt-4 font-display text-xl font-semibold text-ink">
|
||||
{isEn ? "No terms found" : "Nenhum termo encontrado"}
|
||||
</h3>
|
||||
<p className="mx-auto mt-2 max-w-md text-sm text-muted">
|
||||
Nada combina com a busca e os filtros atuais. Tente uma sigla mais curta ou volte para todas as categorias.
|
||||
{isEn
|
||||
? "Nothing matches your current search and filters. Try a shorter acronym or reset to all categories."
|
||||
: "Nada combina com a busca e os filtros atuais. Tente uma sigla mais curta ou volte para todas as categorias."}
|
||||
</p>
|
||||
<button type="button" onClick={limparTodosFiltros} className="btn btn-primary mt-6">
|
||||
<RotateCcw className="h-4 w-4" aria-hidden="true" />
|
||||
Limpar filtros
|
||||
{isEn ? "Clear filters" : "Limpar filtros"}
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
@@ -238,7 +260,7 @@ export default function GlossarioPage() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => copiarLinkTermo(item.slug)}
|
||||
aria-label={`Copiar link para ${item.termo}`}
|
||||
aria-label={isEn ? `Copy link for ${item.termo}` : `Copiar link para ${item.termo}`}
|
||||
className="btn-icon inline-flex h-11 w-11 items-center justify-center rounded-full text-muted transition-colors hover:bg-surface-2 hover:text-accent"
|
||||
>
|
||||
{copiadoSlug === item.slug ? <Check className="h-4 w-4 text-ok" aria-hidden="true" /> : <Link2 className="h-4 w-4" aria-hidden="true" />}
|
||||
@@ -247,16 +269,16 @@ export default function GlossarioPage() {
|
||||
|
||||
<h3 className="mt-3 font-display text-xl font-semibold tracking-[-0.03em] text-ink">{item.termo}</h3>
|
||||
<p className="mt-2 text-[0.9375rem] leading-relaxed text-muted">
|
||||
<TextoComLinks texto={item.definicao} />
|
||||
<TextoComLinks texto={item.definicao} currentLocale={currentLocale} />
|
||||
</p>
|
||||
|
||||
<div className="callout mt-5">
|
||||
<p className="flex items-center gap-1.5 text-sm font-semibold text-ink">
|
||||
<Lightbulb className="h-4 w-4 text-accent" aria-hidden="true" />
|
||||
Na prática
|
||||
{isEn ? "In practice" : "Na prática"}
|
||||
</p>
|
||||
<p className="mt-1">
|
||||
<TextoComLinks texto={item.exemplo} />
|
||||
<TextoComLinks texto={item.exemplo} currentLocale={currentLocale} />
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
@@ -268,17 +290,21 @@ export default function GlossarioPage() {
|
||||
|
||||
<section className="shell pb-20 md:pb-28">
|
||||
<div className="panel p-8 text-center sm:p-12">
|
||||
<h2 className="section-title mx-auto max-w-2xl">Do conceito ao chip certo.</h2>
|
||||
<h2 className="section-title mx-auto max-w-2xl">
|
||||
{isEn ? "From concept to the right chip." : "Do conceito ao chip certo."}
|
||||
</h2>
|
||||
<p className="lede mx-auto mt-4 max-w-2xl">
|
||||
Com os termos em mãos, compare as séries lado a lado ou responda ao seletor para chegar ao modelo que cabe no seu projeto.
|
||||
{isEn
|
||||
? "With the terms in hand, compare series side by side or answer the selector to find the model that fits your project."
|
||||
: "Com os termos em mãos, compare as séries lado a lado ou responda ao seletor para chegar ao modelo que cabe no seu projeto."}
|
||||
</p>
|
||||
<div className="mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row">
|
||||
<Link href="/seletor" className="btn btn-primary w-full sm:w-auto">
|
||||
<Link href={getLocalizedHref("/seletor", currentLocale)} className="btn btn-primary w-full sm:w-auto">
|
||||
<Sliders className="h-4 w-4" aria-hidden="true" />
|
||||
Escolher meu chip
|
||||
{isEn ? "Choose my chip" : "Escolher meu chip"}
|
||||
</Link>
|
||||
<Link href="/series" className="btn btn-ghost w-full sm:w-auto">
|
||||
Explorar as séries
|
||||
<Link href={getLocalizedHref("/series", currentLocale)} className="btn btn-ghost w-full sm:w-auto">
|
||||
{isEn ? "Explore series" : "Explorar as séries"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
@@ -294,7 +320,7 @@ export default function GlossarioPage() {
|
||||
/**
|
||||
* Função utilitária que detecta nomes de séries do ESP32 dentro do texto e os converte em links clicáveis.
|
||||
*/
|
||||
function TextoComLinks({ texto }) {
|
||||
function TextoComLinks({ texto, currentLocale = "pt" }) {
|
||||
if (!texto) return null;
|
||||
const seriesKeys = [
|
||||
"ESP32-S31",
|
||||
@@ -320,7 +346,7 @@ function TextoComLinks({ texto }) {
|
||||
return (
|
||||
<Link
|
||||
key={i}
|
||||
href={`/series/${parte}`}
|
||||
href={getLocalizedHref(`/series/${parte}`, currentLocale)}
|
||||
className="font-semibold text-accent underline decoration-accent/30 underline-offset-2 hover:decoration-accent"
|
||||
>
|
||||
{parte}
|
||||
@@ -331,4 +357,4 @@ function TextoComLinks({ texto }) {
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
import { notFound } from "next/navigation";
|
||||
import { JetBrains_Mono, Manrope, Space_Grotesk } from "next/font/google";
|
||||
import { NextIntlClientProvider } from "next-intl";
|
||||
import { getMessages } from "next-intl/server";
|
||||
import { routing } from "@/i18n/routing";
|
||||
import { ENABLED_LOCALES } from "@/i18n/links";
|
||||
import "../globals.css";
|
||||
import Providers from "@/components/Providers";
|
||||
import { SITE, jsonLd } from "@/lib/seo";
|
||||
|
||||
const spaceGrotesk = Space_Grotesk({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-space-grotesk",
|
||||
display: "swap",
|
||||
weight: ["500", "600", "700"],
|
||||
});
|
||||
|
||||
const manrope = Manrope({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-manrope",
|
||||
display: "swap",
|
||||
weight: ["400", "500", "600", "700"],
|
||||
});
|
||||
|
||||
const jetbrainsMono = JetBrains_Mono({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-jetbrains",
|
||||
display: "swap",
|
||||
weight: ["400", "500", "600"],
|
||||
});
|
||||
|
||||
const LANG_MAP = {
|
||||
pt: "pt-BR",
|
||||
en: "en",
|
||||
es: "es-419",
|
||||
fr: "fr",
|
||||
de: "de",
|
||||
"zh-CN": "zh-CN",
|
||||
};
|
||||
|
||||
export function generateStaticParams() {
|
||||
return ENABLED_LOCALES.map((locale) => ({ locale }));
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
|
||||
const ogLocaleMap = {
|
||||
pt: "pt_BR",
|
||||
en: "en_US",
|
||||
es: "es_419",
|
||||
fr: "fr_FR",
|
||||
de: "de_DE",
|
||||
"zh-CN": "zh_CN",
|
||||
};
|
||||
|
||||
const alternateLocales = ENABLED_LOCALES.filter((l) => l !== locale).map((l) => ogLocaleMap[l]);
|
||||
|
||||
const titleDefault = isEn
|
||||
? "ESPDocs · ESP32 Open Documentation"
|
||||
: "ESPDocs · Documentação do ESP32 em português";
|
||||
|
||||
const description = isEn
|
||||
? "Specifications, pinouts, comparison and selection of 12 ESP32 microcontroller series. Datasheets, peripherals, hardware security and connection diagrams."
|
||||
: "Especificações, pinagem, comparação e seleção das 12 séries de microcontroladores ESP32, em português brasileiro. Datasheets, periféricos, segurança em hardware e diagramas de conexão.";
|
||||
|
||||
const keywords = isEn
|
||||
? [
|
||||
"ESP32", "ESP32 documentation", "ESP32 pinout",
|
||||
"ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4", "ESP32-H2",
|
||||
"compare ESP32", "which ESP32 to choose", "ESP32 datasheet",
|
||||
"microcontroller", "Espressif", "ESP-IDF", "IoT", "embedded systems",
|
||||
]
|
||||
: [
|
||||
"ESP32", "ESP32 português", "documentação ESP32", "pinout ESP32",
|
||||
"ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4", "ESP32-H2",
|
||||
"comparar ESP32", "qual ESP32 escolher", "datasheet ESP32",
|
||||
"microcontrolador", "Espressif", "ESP-IDF", "IoT", "sistemas embarcados",
|
||||
];
|
||||
|
||||
const languages = Object.fromEntries(
|
||||
ENABLED_LOCALES.map((l) => [LANG_MAP[l] || l, `/${l}`])
|
||||
);
|
||||
if (ENABLED_LOCALES.includes("en")) {
|
||||
languages["x-default"] = "/en";
|
||||
}
|
||||
|
||||
return {
|
||||
metadataBase: new URL(SITE.url),
|
||||
title: {
|
||||
default: titleDefault,
|
||||
template: "%s · ESPDocs",
|
||||
},
|
||||
description,
|
||||
applicationName: "ESPDocs",
|
||||
authors: [{ name: "Lucas Rayan Guerra", url: "https://lucasrguerra.dev.br" }],
|
||||
creator: "Lucas Rayan Guerra",
|
||||
publisher: "Ciência Embarcada",
|
||||
category: "technology",
|
||||
keywords,
|
||||
alternates: {
|
||||
canonical: `/${locale}`,
|
||||
languages,
|
||||
},
|
||||
openGraph: {
|
||||
type: "website",
|
||||
locale: ogLocaleMap[locale] || "pt_BR",
|
||||
alternateLocale: alternateLocales.length > 0 ? alternateLocales : undefined,
|
||||
url: `${SITE.url}/${locale}`,
|
||||
siteName: SITE.nome,
|
||||
title: titleDefault,
|
||||
description: isEn
|
||||
? "Specifications, pinouts, comparison and selection of 12 ESP32 microcontroller series."
|
||||
: "Especificações, pinagem, comparação e seleção das 12 séries de microcontroladores ESP32, em português brasileiro.",
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: titleDefault,
|
||||
description: isEn
|
||||
? "Specifications, pinouts, comparison and selection of 12 ESP32 series."
|
||||
: "Especificações, pinagem, comparação e seleção das 12 séries de ESP32, em português.",
|
||||
},
|
||||
robots: {
|
||||
index: true,
|
||||
follow: true,
|
||||
googleBot: {
|
||||
index: true,
|
||||
follow: true,
|
||||
"max-image-preview": "large",
|
||||
"max-snippet": -1,
|
||||
"max-video-preview": -1,
|
||||
},
|
||||
},
|
||||
icons: {
|
||||
icon: [
|
||||
{ url: "/favicon.ico", sizes: "48x48", type: "image/x-icon" },
|
||||
{ url: "/favicon-48x48.png", sizes: "48x48", type: "image/png" },
|
||||
{ url: "/favicon-32x32.png", sizes: "32x32", type: "image/png" },
|
||||
{ url: "/favicon-16x16.png", sizes: "16x16", type: "image/png" },
|
||||
{ url: "/icon-192.png", sizes: "192x192", type: "image/png" },
|
||||
{ url: "/icon-512.png", sizes: "512x512", type: "image/png" },
|
||||
{ url: "/icon.svg", type: "image/svg+xml" },
|
||||
],
|
||||
apple: [
|
||||
{ url: "/apple-touch-icon.png", sizes: "180x180", type: "image/png" },
|
||||
],
|
||||
shortcut: "/favicon.ico",
|
||||
},
|
||||
manifest: "/site.webmanifest",
|
||||
formatDetection: { telephone: false, address: false, email: false },
|
||||
};
|
||||
}
|
||||
|
||||
export const viewport = {
|
||||
themeColor: [
|
||||
{ media: "(prefers-color-scheme: light)", color: "#f5f6f8" },
|
||||
{ media: "(prefers-color-scheme: dark)", color: "#07090d" },
|
||||
],
|
||||
};
|
||||
|
||||
export default async function RootLayout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
if (!ENABLED_LOCALES.includes(locale)) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const lang = LANG_MAP[locale] || locale;
|
||||
const messages = await getMessages();
|
||||
|
||||
return (
|
||||
<html lang={lang} className={`${spaceGrotesk.variable} ${manrope.variable} ${jetbrainsMono.variable}`} suppressHydrationWarning>
|
||||
<head>
|
||||
{/* Dados estruturados do site e da organização. É o que permite ao
|
||||
Google montar o box de busca interna e entender a autoria. */}
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.siteESociedade(locale)) }}
|
||||
/>
|
||||
</head>
|
||||
<body className="font-sans antialiased bg-canvas text-ink overflow-x-clip" suppressHydrationWarning>
|
||||
<a
|
||||
href="#conteudo"
|
||||
className="sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-4 focus:z-[200] focus:rounded-full focus:bg-ink focus:px-5 focus:py-3 focus:text-sm focus:font-semibold focus:text-canvas"
|
||||
>
|
||||
{messages?.Common?.skipToContent || "Pular para o conteúdo"}
|
||||
</a>
|
||||
<NextIntlClientProvider locale={locale} messages={messages}>
|
||||
<Providers>
|
||||
{children}
|
||||
</Providers>
|
||||
</NextIntlClientProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { notFound } from "next/navigation";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import BookCover from "@/components/BookCover";
|
||||
@@ -16,19 +17,29 @@ import {
|
||||
Wifi,
|
||||
} from "lucide-react";
|
||||
|
||||
export const metadata = paginaMeta({
|
||||
titulo: "Microcontroladores ESP32, o livro",
|
||||
descricao:
|
||||
"Conheça o livro Microcontroladores ESP32: conectividade, eficiência e desempenho. 12 partes e 78 capítulos em português sobre arquitetura, energia, rádio, periféricos e firmware.",
|
||||
caminho: "/livro",
|
||||
keywords: [
|
||||
"livro ESP32",
|
||||
"Microcontroladores ESP32",
|
||||
"livro de ESP32 em português",
|
||||
"Lucas Rayan Guerra",
|
||||
"Ciência Embarcada",
|
||||
],
|
||||
});
|
||||
export function generateStaticParams() {
|
||||
return [{ locale: "pt" }];
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
if (locale !== "pt") {
|
||||
return {};
|
||||
}
|
||||
return paginaMeta({
|
||||
titulo: "Microcontroladores ESP32, o livro",
|
||||
descricao:
|
||||
"Conheça o livro Microcontroladores ESP32: conectividade, eficiência e desempenho. 12 partes e 78 capítulos em português sobre arquitetura, energia, rádio, periféricos e firmware.",
|
||||
caminho: "/pt/livro",
|
||||
keywords: [
|
||||
"livro ESP32",
|
||||
"Microcontroladores ESP32",
|
||||
"livro de ESP32 em português",
|
||||
"Lucas Rayan Guerra",
|
||||
"Ciência Embarcada",
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
const CHAPTERS = [
|
||||
{
|
||||
@@ -128,7 +139,11 @@ const FACTS = [
|
||||
["ISBN", SITE.livroIsbn],
|
||||
];
|
||||
|
||||
export default function LivroPage() {
|
||||
export default async function LivroPage({ params }) {
|
||||
const { locale } = await params;
|
||||
if (locale !== "pt") {
|
||||
notFound();
|
||||
}
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
<script
|
||||
@@ -0,0 +1,81 @@
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import Link from "next/link";
|
||||
import { ArrowRight, BookOpen, Compass, Scale, SlidersHorizontal } from "lucide-react";
|
||||
import { getLocale } from "next-intl/server";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
|
||||
export const metadata = {
|
||||
title: "404",
|
||||
robots: { index: false, follow: false },
|
||||
};
|
||||
|
||||
const CAMINHOS_PT = [
|
||||
{ href: "/series", icon: Compass, titulo: "Séries ESP32", texto: "As 12 famílias, com pinagem e especificações." },
|
||||
{ href: "/seletor", icon: SlidersHorizontal, titulo: "Seletor de chip", texto: "Responda a oito perguntas e receba os modelos indicados." },
|
||||
{ href: "/comparacao", icon: Scale, titulo: "Comparador", texto: "Até quatro séries lado a lado." },
|
||||
{ href: "/glossario", icon: BookOpen, titulo: "Glossário", texto: "Termos de hardware explicados em português." },
|
||||
];
|
||||
|
||||
const CAMINHOS_EN = [
|
||||
{ href: "/series", icon: Compass, titulo: "ESP32 Series", texto: "The 12 families, with pinouts and specifications." },
|
||||
{ href: "/seletor", icon: SlidersHorizontal, titulo: "Chip selector", texto: "Answer eight questions and get recommended models." },
|
||||
{ href: "/comparacao", icon: Scale, titulo: "Comparator", texto: "Up to four series side by side." },
|
||||
{ href: "/glossario", icon: BookOpen, titulo: "Glossary", texto: "Hardware terms explained clearly." },
|
||||
];
|
||||
|
||||
export default async function NotFound() {
|
||||
let locale = "pt";
|
||||
try {
|
||||
locale = await getLocale();
|
||||
} catch {
|
||||
locale = "pt";
|
||||
}
|
||||
const isEn = locale === "en";
|
||||
const caminhos = isEn ? CAMINHOS_EN : CAMINHOS_PT;
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
<Header />
|
||||
|
||||
<main id="conteudo" className="shell section">
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<p className="eyebrow justify-center">{isEn ? "Error 404" : "Erro 404"}</p>
|
||||
<h1 className="page-title mt-4">{isEn ? "This page does not exist." : "Essa página não existe."}</h1>
|
||||
<p className="lede mx-auto mt-5 max-w-xl">
|
||||
{isEn
|
||||
? "The address may have changed or was mistyped. Choose one of these paths to continue."
|
||||
: "O endereço pode ter mudado ou estar digitado errado. Escolha um destes caminhos para continuar."}
|
||||
</p>
|
||||
<div className="mt-8 flex justify-center">
|
||||
<Link href={isEn ? "/en" : "/"} className="btn btn-primary">
|
||||
{isEn ? "Back to home" : "Voltar ao início"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul className="mx-auto mt-14 grid max-w-4xl gap-3 sm:grid-cols-2">
|
||||
{caminhos.map(({ href, icon: Icon, titulo, texto }) => {
|
||||
const targetHref = isEn ? getLocalizedHref(href, "en") : href;
|
||||
return (
|
||||
<li key={href}>
|
||||
<Link href={targetHref} className="card card-interactive group flex h-full items-start gap-4 p-5">
|
||||
<span className="grid h-10 w-10 shrink-0 place-items-center rounded-full bg-accent-soft text-accent">
|
||||
<Icon className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<span>
|
||||
<span className="block font-semibold text-ink">{titulo}</span>
|
||||
<span className="mt-0.5 block text-sm text-muted">{texto}</span>
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,453 @@
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import BookCover from "@/components/BookCover";
|
||||
import Link from "next/link";
|
||||
import seriesDataPt from "@/public/series.json";
|
||||
import frameworksDataPt from "@/public/frameworks.json";
|
||||
import seriesDataEn from "@/data/en/series.json";
|
||||
import frameworksDataEn from "@/data/en/frameworks.json";
|
||||
import { SITE } from "@/lib/seo";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
import {
|
||||
AlertTriangle,
|
||||
ArrowRight,
|
||||
ArrowUpRight,
|
||||
BookOpen,
|
||||
Box,
|
||||
Cpu,
|
||||
Scale,
|
||||
SlidersHorizontal,
|
||||
Terminal,
|
||||
} from "lucide-react";
|
||||
|
||||
const FEATURED = ["ESP32", "ESP32-S3", "ESP32-C6", "ESP32-C3", "ESP32-P4", "ESP32-H2"];
|
||||
|
||||
const TOOLS_PT = [
|
||||
{
|
||||
href: "/seletor",
|
||||
title: "Seletor inteligente",
|
||||
desc: "Responda oito perguntas sobre o projeto e receba os chips mais compatíveis, com justificativa técnica.",
|
||||
icon: SlidersHorizontal,
|
||||
action: "Encontrar meu chip",
|
||||
},
|
||||
{
|
||||
href: "/comparacao",
|
||||
title: "Comparador de séries",
|
||||
desc: "Coloque até quatro modelos lado a lado e compare núcleos, rádio, memória, periféricos e segurança.",
|
||||
icon: Scale,
|
||||
action: "Comparar agora",
|
||||
},
|
||||
{
|
||||
href: "/diagnostico",
|
||||
title: "Diagnóstico de falhas",
|
||||
desc: "Causas e correções para brownout, bootloop, Guru Meditation, watchdog e falhas de flash.",
|
||||
icon: AlertTriangle,
|
||||
action: "Abrir diagnóstico",
|
||||
},
|
||||
{
|
||||
href: "/componentes",
|
||||
title: "Component Registry",
|
||||
desc: "Drivers, bibliotecas e BSPs do registro oficial da Espressif, com manifesto pronto para o projeto.",
|
||||
icon: Box,
|
||||
action: "Explorar componentes",
|
||||
},
|
||||
{
|
||||
href: "/frameworks",
|
||||
title: "Frameworks e SDKs",
|
||||
desc: "ESP-IDF, Arduino, Rust, Matter, MicroPython e as ferramentas que ficam em volta do chip.",
|
||||
icon: Terminal,
|
||||
action: "Ver frameworks",
|
||||
},
|
||||
{
|
||||
href: "/catalogo",
|
||||
title: "Catálogo de placas",
|
||||
desc: "DevKits e módulos reais, com interface USB, sensores integrados e link para a loja oficial.",
|
||||
icon: Cpu,
|
||||
action: "Ver placas",
|
||||
},
|
||||
];
|
||||
|
||||
const TOOLS_EN = [
|
||||
{
|
||||
href: "/seletor",
|
||||
title: "Smart Selector",
|
||||
desc: "Answer eight questions about your project and find recommended chips, backed by technical rationale.",
|
||||
icon: SlidersHorizontal,
|
||||
action: "Find my chip",
|
||||
},
|
||||
{
|
||||
href: "/comparacao",
|
||||
title: "Series Comparator",
|
||||
desc: "Place up to four models side by side and compare cores, radio, memory, peripherals, and security.",
|
||||
icon: Scale,
|
||||
action: "Compare now",
|
||||
},
|
||||
{
|
||||
href: "/diagnostico",
|
||||
title: "Fault Diagnostics",
|
||||
desc: "Root causes and fixes for brownout, bootloop, Guru Meditation, watchdog, and flash errors.",
|
||||
icon: AlertTriangle,
|
||||
action: "Open diagnostics",
|
||||
},
|
||||
{
|
||||
href: "/componentes",
|
||||
title: "Component Registry",
|
||||
desc: "Drivers, libraries and BSPs from the official Espressif registry, with ready-to-use manifests.",
|
||||
icon: Box,
|
||||
action: "Explore components",
|
||||
},
|
||||
{
|
||||
href: "/frameworks",
|
||||
title: "Frameworks & SDKs",
|
||||
desc: "ESP-IDF, Arduino, Rust, Matter, MicroPython and the tools built around the silicon.",
|
||||
icon: Terminal,
|
||||
action: "View frameworks",
|
||||
},
|
||||
{
|
||||
href: "/catalogo",
|
||||
title: "Board Catalog",
|
||||
desc: "Real DevKits and modules, with USB interfaces, integrated sensors and direct store links.",
|
||||
icon: Cpu,
|
||||
action: "View boards",
|
||||
},
|
||||
];
|
||||
|
||||
const ERRORS_PT = [
|
||||
{
|
||||
code: "Brownout detector was triggered",
|
||||
cause: "Queda de tensão na inicialização do rádio.",
|
||||
fix: "Capacitor de 10–100 µF junto ao chip e fonte de 5 V com corrente suficiente.",
|
||||
},
|
||||
{
|
||||
code: "Guru Meditation Error",
|
||||
cause: "Ponteiro inválido, stack overflow ou uso incorreto de interrupção.",
|
||||
fix: "Leia o backtrace com addr2line e dimensione a stack da task no FreeRTOS.",
|
||||
},
|
||||
{
|
||||
code: "ADC2 indisponível com Wi-Fi",
|
||||
cause: "O controlador de rádio reserva o ADC2 enquanto está ativo.",
|
||||
fix: "Use os pinos do ADC1 para sensores analógicos que convivem com o Wi-Fi.",
|
||||
},
|
||||
{
|
||||
code: "Flash Read err / bootloader",
|
||||
cause: "Tensão ou modo de flash incorretos, ou pino de strapping preso no boot.",
|
||||
fix: "Confira 3,3 V, pull-ups de boot e a configuração de flash no esptool.",
|
||||
},
|
||||
];
|
||||
|
||||
const ERRORS_EN = [
|
||||
{
|
||||
code: "Brownout detector was triggered",
|
||||
cause: "Voltage sag upon radio startup.",
|
||||
fix: "10–100 µF capacitor close to chip and a 5 V supply with sufficient current.",
|
||||
},
|
||||
{
|
||||
code: "Guru Meditation Error",
|
||||
cause: "Invalid pointer, stack overflow, or improper ISR usage.",
|
||||
fix: "Inspect backtrace with addr2line and properly size FreeRTOS task stacks.",
|
||||
},
|
||||
{
|
||||
code: "ADC2 indisponível com Wi-Fi",
|
||||
cause: "Internal radio controller reserves ADC2 while active.",
|
||||
fix: "Use ADC1 pins for analog sensors operating alongside Wi-Fi.",
|
||||
},
|
||||
{
|
||||
code: "Flash Read err / bootloader",
|
||||
cause: "Incorrect flash voltage/mode or strapping pin pulled during boot.",
|
||||
fix: "Check 3.3 V rail, boot pull-ups, and flash configuration in esptool.",
|
||||
},
|
||||
];
|
||||
|
||||
export default async function Home({ params }) {
|
||||
const { locale } = await params;
|
||||
const isPt = locale === "pt";
|
||||
const getLinkHref = (href) => getLocalizedHref(`/${locale}${href}`, locale);
|
||||
|
||||
const seriesData = isPt ? seriesDataPt : seriesDataEn;
|
||||
const frameworksData = isPt ? frameworksDataPt : frameworksDataEn;
|
||||
const tools = isPt ? TOOLS_PT : TOOLS_EN;
|
||||
const errors = isPt ? ERRORS_PT : ERRORS_EN;
|
||||
|
||||
const seriesCount = Object.keys(seriesData).length;
|
||||
const frameworkCount = Object.keys(frameworksData).length;
|
||||
const featured = FEATURED.map((key) => [key, seriesData[key]]).filter(([, serie]) => Boolean(serie));
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
<Header />
|
||||
|
||||
<main id="conteudo">
|
||||
<section className="shell pb-10 pt-14 sm:pt-20 lg:pb-14 lg:pt-24">
|
||||
<div className="mx-auto max-w-4xl text-center">
|
||||
<span className="chip chip-accent">
|
||||
<Cpu className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
{isPt ? "Documentação aberta do ESP32" : "Open ESP32 documentation"}
|
||||
</span>
|
||||
<h1 className="display mt-6 text-[clamp(2.9rem,7.4vw,5.4rem)]">
|
||||
{isPt ? (
|
||||
<>
|
||||
O ESP32,
|
||||
<br className="sm:hidden" /> sem ruído.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
The ESP32,
|
||||
<br className="sm:hidden" /> without noise.
|
||||
</>
|
||||
)}
|
||||
</h1>
|
||||
<p className="lede mx-auto mt-6 max-w-2xl">
|
||||
{isPt
|
||||
? "Especificações, pinagem, comparações e diagnóstico em uma leitura só. Menos tradução de datasheet, mais tempo com o protótipo na bancada."
|
||||
: "Specifications, pinouts, comparisons and diagnostics in a single read. Less datasheet translation, more workbench time."}
|
||||
</p>
|
||||
|
||||
<div className="mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row">
|
||||
<Link href={getLinkHref("/seletor")} className="btn btn-primary w-full sm:w-auto">
|
||||
<SlidersHorizontal className="h-4 w-4" aria-hidden="true" />
|
||||
{isPt ? "Escolher meu chip" : "Choose my chip"}
|
||||
</Link>
|
||||
<Link href={getLinkHref("/series")} className="btn btn-ghost w-full sm:w-auto">
|
||||
{isPt ? (
|
||||
<>Explorar as {seriesCount} séries</>
|
||||
) : (
|
||||
<>Explore the {seriesCount} series</>
|
||||
)}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<p className="mt-7 flex flex-wrap items-center justify-center gap-x-5 gap-y-2 text-sm text-muted">
|
||||
<span><strong className="font-semibold text-ink">{seriesCount}</strong> {isPt ? "séries" : "series"}</span>
|
||||
<span aria-hidden="true" className="text-line-strong">·</span>
|
||||
<span><strong className="font-semibold text-ink">{frameworkCount}</strong> frameworks</span>
|
||||
{isPt ? (
|
||||
<>
|
||||
<span aria-hidden="true" className="text-line-strong">·</span>
|
||||
<span><strong className="font-semibold text-ink">78</strong> capítulos no livro</span>
|
||||
<span aria-hidden="true" className="text-line-strong">·</span>
|
||||
<span>100% em português</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span aria-hidden="true" className="text-line-strong">·</span>
|
||||
<span>100% in English</span>
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="panel mt-12 overflow-hidden sm:mt-16">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3 px-5 py-4 sm:px-7">
|
||||
<div>
|
||||
<h2 className="text-sm font-semibold text-ink">{isPt ? "Séries em destaque" : "Featured series"}</h2>
|
||||
<p className="mt-0.5 text-xs text-muted">
|
||||
{isPt ? "O essencial de cada família, antes de abrir o datasheet." : "The essentials of each family before opening the datasheet."}
|
||||
</p>
|
||||
</div>
|
||||
<Link href={getLinkHref("/series")} className="inline-flex min-h-11 items-center gap-1.5 text-sm font-medium text-accent transition-colors hover:text-accent-strong">
|
||||
{isPt ? "Índice completo" : "Full index"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-px border-t border-line bg-line sm:grid-cols-2 lg:grid-cols-3">
|
||||
{featured.map(([key, serie]) => (
|
||||
<Link
|
||||
key={key}
|
||||
href={getLinkHref(`/series/${key}`)}
|
||||
className="group flex min-w-0 flex-col bg-surface p-5 transition-colors duration-300 hover:bg-surface-2 sm:p-6"
|
||||
>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="min-w-0">
|
||||
<h3 className="font-display text-xl font-semibold tracking-[-0.035em] text-ink">{key}</h3>
|
||||
<p className="mt-1 truncate text-xs text-muted">{serie.arquitetura}</p>
|
||||
</div>
|
||||
<span className="grid h-9 w-9 shrink-0 place-items-center rounded-full bg-accent-soft text-accent transition-transform duration-300 group-hover:scale-105">
|
||||
<Cpu className="h-4 w-4" aria-hidden="true" />
|
||||
</span>
|
||||
</div>
|
||||
<p className="mt-5 line-clamp-2 text-sm leading-relaxed text-muted">{serie.descricao}</p>
|
||||
<div className="mt-5 flex items-center justify-between gap-3 border-t border-line pt-3.5">
|
||||
<span className="truncate font-mono text-[0.6875rem] text-ink-soft">{serie.frequencia}</span>
|
||||
<span className="inline-flex shrink-0 items-center gap-1 text-xs font-medium text-accent">
|
||||
{isPt ? "Ficha" : "Spec sheet"}
|
||||
<ArrowUpRight className="h-3.5 w-3.5 transition-transform duration-300 group-hover:-translate-y-0.5 group-hover:translate-x-0.5" aria-hidden="true" />
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{isPt && (
|
||||
<section className="shell section pt-8 sm:pt-12" aria-labelledby="livro-titulo">
|
||||
<div className="relative isolate overflow-hidden rounded-[2rem] bg-[#0b0d10] ring-1 ring-white/10 dark:bg-[#05070a] dark:ring-white/15 sm:rounded-[2.5rem]">
|
||||
<div
|
||||
className="pointer-events-none absolute -left-24 top-1/2 -z-10 h-80 w-80 -translate-y-1/2 rounded-full bg-[#2dd4bf]/15 blur-3xl"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div className="grid lg:grid-cols-[0.82fr_1.18fr]">
|
||||
<div className="order-1 flex flex-col justify-center p-7 sm:p-10 lg:order-2 lg:p-14">
|
||||
<span className="inline-flex w-fit items-center gap-2 rounded-full border border-white/15 bg-white/5 px-3 py-1 text-xs font-semibold text-[#75cdc1]">
|
||||
<BookOpen className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
Livro novo
|
||||
</span>
|
||||
<h2 id="livro-titulo" className="mt-5 font-display text-[clamp(2rem,4.2vw,3.2rem)] font-semibold leading-[1.05] tracking-[-0.04em] text-[#f4f6f8]">
|
||||
{SITE.livroTitulo}
|
||||
</h2>
|
||||
<p className="mt-2 text-base text-[#a6afbd]">{SITE.livroSubtitulo}</p>
|
||||
<p className="mt-5 max-w-xl text-sm leading-relaxed text-[#c4cbd5]">
|
||||
Um percurso completo pelo hardware e pelo firmware do ESP32: da arquitetura do chip
|
||||
à implantação de produtos conectados. São 12 partes e 78 capítulos sobre Arduino,
|
||||
ESP-IDF, FreeRTOS, Wi-Fi, BLE, Thread e Matter, periféricos, depuração, baixo consumo
|
||||
e segurança.
|
||||
</p>
|
||||
|
||||
<p className="mt-6 flex flex-wrap items-center gap-x-3 gap-y-1.5 text-xs text-[#a6afbd]">
|
||||
<span>12 partes</span>
|
||||
<span aria-hidden="true" className="text-white/20">·</span>
|
||||
<span>78 capítulos</span>
|
||||
<span aria-hidden="true" className="text-white/20">·</span>
|
||||
<span>ISBN {SITE.livroIsbn}</span>
|
||||
</p>
|
||||
|
||||
<div className="mt-7 flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center">
|
||||
<a
|
||||
href={SITE.livroAmazon}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex min-h-11 items-center justify-center gap-2 rounded-full bg-[#2dd4bf] px-5 text-sm font-semibold text-[#06201d] transition-colors duration-300 hover:bg-[#5eead4]"
|
||||
>
|
||||
Comprar digital
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
<a
|
||||
href={SITE.livroUiclap}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex min-h-11 items-center justify-center gap-2 rounded-full border border-white/20 px-5 text-sm font-semibold text-[#f4f6f8] transition-colors duration-300 hover:border-white/40 hover:bg-white/5"
|
||||
>
|
||||
Comprar impresso
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
<Link href="/pt/livro" className="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-full px-3 text-sm font-medium text-[#a6afbd] transition-colors duration-300 hover:text-[#f4f6f8]">
|
||||
Ficha completa
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="order-2 flex items-center justify-center border-t border-white/10 p-8 sm:p-12 lg:order-1 lg:border-r lg:border-t-0 lg:p-14">
|
||||
<div className="relative w-[min(15.5rem,68%)] lg:w-[min(17rem,100%)]">
|
||||
<div className="absolute -inset-10 -z-10 rounded-full bg-[#2dd4bf]/10 blur-3xl" aria-hidden="true" />
|
||||
<BookCover />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<section className="shell section" aria-labelledby="ferramentas-titulo">
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<p className="eyebrow">{isPt ? "Ferramentas" : "Tools"}</p>
|
||||
<h2 id="ferramentas-titulo" className="display mt-4 text-[clamp(2rem,4.8vw,3.4rem)]">
|
||||
{isPt ? "Comece pelo problema." : "Start with the problem."}
|
||||
</h2>
|
||||
<p className="lede mt-4">
|
||||
{isPt
|
||||
? "Cada ferramenta resolve uma etapa concreta do projeto, sem cadastro e sem rodeio."
|
||||
: "Each tool addresses a concrete development phase, with no sign-ups and zero fluff."}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{tools.map((tool) => {
|
||||
const Icon = tool.icon;
|
||||
return (
|
||||
<Link key={tool.href} href={getLinkHref(tool.href)} className="card card-interactive group flex flex-col p-5 sm:p-6">
|
||||
<span className="grid h-11 w-11 place-items-center rounded-2xl bg-accent-soft text-accent">
|
||||
<Icon className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<h3 className="mt-5 font-display text-lg font-semibold tracking-[-0.025em] text-ink">{tool.title}</h3>
|
||||
<p className="mt-2 flex-1 text-sm leading-relaxed text-muted">{tool.desc}</p>
|
||||
<span className="mt-5 inline-flex items-center gap-1.5 text-sm font-medium text-accent">
|
||||
{tool.action}
|
||||
<ArrowRight className="h-4 w-4 transition-transform duration-300 group-hover:translate-x-0.5" aria-hidden="true" />
|
||||
</span>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="shell section pt-0" aria-labelledby="diagnostico-titulo">
|
||||
<div className="grid items-start gap-10 lg:grid-cols-[0.78fr_1.22fr] lg:gap-16">
|
||||
<div className="lg:sticky lg:top-28">
|
||||
<p className="eyebrow">{isPt ? "Diagnóstico" : "Diagnostics"}</p>
|
||||
<h2 id="diagnostico-titulo" className="display mt-4 text-[clamp(2rem,4.8vw,3.4rem)]">
|
||||
{isPt ? "O primeiro boot não precisa virar noite." : "First boot doesn't have to take all night."}
|
||||
</h2>
|
||||
<p className="lede mt-4">
|
||||
{isPt
|
||||
? "Os erros mais comuns têm causa conhecida. O guia parte da mensagem no terminal e chega ao ajuste de hardware ou firmware."
|
||||
: "Common errors have known causes. This guide starts with the serial terminal log and leads to the hardware or firmware adjustment."}
|
||||
</p>
|
||||
<Link href={getLinkHref("/diagnostico")} className="btn btn-accent mt-7">
|
||||
<AlertTriangle className="h-4 w-4" aria-hidden="true" />
|
||||
{isPt ? "Abrir os 30+ diagnósticos" : "Open the 30+ diagnostics"}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="panel-dark min-w-0 overflow-hidden rounded-[1.75rem]">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3 border-b border-white/10 px-5 py-4 sm:px-6">
|
||||
<span className="inline-flex items-center gap-2 font-mono text-xs text-[#75cdc1]">
|
||||
<Terminal className="h-4 w-4" aria-hidden="true" />
|
||||
boot.log
|
||||
</span>
|
||||
<span className="text-xs text-[#a6afbd]">{isPt ? "4 exemplos de 30+" : "4 examples of 30+"}</span>
|
||||
</div>
|
||||
<div className="divide-y divide-white/10">
|
||||
{errors.map((item) => (
|
||||
<Link key={item.code} href={getLinkHref("/diagnostico")} className="group grid gap-2 px-5 py-5 transition-colors duration-300 hover:bg-white/[0.035] sm:px-6">
|
||||
<span className="break-words font-mono text-[0.75rem] font-medium leading-relaxed text-[#ffb39b]">{item.code}</span>
|
||||
<span className="text-sm font-medium text-[#f4f6f8]">{item.cause}</span>
|
||||
<span className="text-xs leading-relaxed text-[#a6afbd]">{item.fix}</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="shell pb-20 pt-4 md:pb-28">
|
||||
<div className="mx-auto max-w-3xl text-center">
|
||||
<p className="eyebrow">{isPt ? "Curadoria independente" : "Independent curation"}</p>
|
||||
<h2 className="display mt-4 text-[clamp(2rem,4.5vw,3.2rem)]">
|
||||
{isPt ? "Feito para consultar no meio do projeto." : "Built for quick lookup mid-project."}
|
||||
</h2>
|
||||
<p className="lede mx-auto mt-4 max-w-2xl">
|
||||
{isPt
|
||||
? "O ESPDocs organiza dados públicos da Espressif e aponta sempre para a fonte oficial. Para decisões críticas, o datasheet e o Technical Reference Manual continuam sendo a palavra final."
|
||||
: "ESPDocs organizes public Espressif data and points directly to official sources. For critical engineering decisions, the datasheet and Technical Reference Manual remain the definitive authority."}
|
||||
</p>
|
||||
<div className="mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row">
|
||||
<Link href={getLinkHref("/glossario")} className="btn btn-ghost w-full sm:w-auto">
|
||||
<BookOpen className="h-4 w-4" aria-hidden="true" />
|
||||
{isPt ? "Glossário" : "Glossary"}
|
||||
</Link>
|
||||
<Link href={getLinkHref("/sobre")} className="btn btn-primary w-full sm:w-auto">
|
||||
{isPt ? "Sobre o projeto" : "About the project"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
return paginaMeta({
|
||||
titulo: isEn ? "Which ESP32 to Choose" : "Qual ESP32 escolher",
|
||||
descricao: isEn
|
||||
? "Answer simple questions about connectivity (Wi-Fi 6, 5GHz, Matter), power, peripherals, and security or use the parametric filter to find the perfect ESP32."
|
||||
: "Responda a perguntas simples sobre conectividade (Wi-Fi 6, 5GHz, Matter), energia, periféricos e segurança ou use o filtro paramétrico para encontrar o ESP32 perfeito.",
|
||||
caminho: "/seletor",
|
||||
locale,
|
||||
keywords: isEn
|
||||
? ["which ESP32 to choose", "which ESP32 to use", "choose microcontroller", "ESP32 for my project", "compare ESP32"]
|
||||
: ["qual ESP32 escolher", "qual ESP32 usar", "escolher microcontrolador", "ESP32 para meu projeto", "comparar ESP32"],
|
||||
});
|
||||
}
|
||||
|
||||
const faqsPt = [
|
||||
{
|
||||
pergunta: "Qual ESP32 escolher para iniciantes?",
|
||||
resposta: "Para quem está começando no mundo Maker e IoT, o ESP32 clássico (NodeMCU/DevKitC) ou o ESP32-C3 são as melhores opções devido à vasta quantidade de bibliotecas, exemplos prontos no Arduino IDE e farta documentação em português.",
|
||||
},
|
||||
{
|
||||
pergunta: "Qual ESP32 tem suporte a Wi-Fi 6, Bluetooth 6 e Thread/Zigbee/Matter?",
|
||||
resposta: "O ESP32-C6 e o ESP32-C5 são as melhores séries para redes modernas. O ESP32-C6 oferece Wi-Fi 6 (2.4 GHz) e rádio 802.15.4 (Zigbee 3.0 / Thread / Matter). Já o ESP32-C5 é o primeiro a oferecer suporte a Wi-Fi 6 Dual-Band operando em 2.4 GHz e 5 GHz simultaneamente.",
|
||||
},
|
||||
{
|
||||
pergunta: "Qual o ESP32 mais potente para Inteligência Artificial (TinyML) e Displays?",
|
||||
resposta: "O ESP32-P4 (dual-core RISC-V a 400 MHz com extensões vetoriais de IA, interfaces MIPI-CSI/DSI para câmeras/telas e até 64 MB de PSRAM) e o ESP32-S3 (dual-core Xtensa a 240 MHz com aceleradores vetoriais para redes neurais e telas LCD RGB) são os mais velozes para IA na borda e interfaces gráficas ricas.",
|
||||
},
|
||||
{
|
||||
pergunta: "Qual ESP32 consome menos energia para projetos a bateria?",
|
||||
resposta: "Microcontroladores com arquitetura RISC-V compacta e coprocessador ULP, como o ESP32-C2, ESP32-C3 e ESP32-H2 (focado em 802.15.4 sem rádio Wi-Fi), oferecem correntes de deep sleep extremamente baixas (na faixa de 5 µA a 10 µA).",
|
||||
},
|
||||
];
|
||||
|
||||
const faqsEn = [
|
||||
{
|
||||
pergunta: "Which ESP32 to choose for beginners?",
|
||||
resposta: "For makers and developers starting out in IoT, the classic ESP32 (NodeMCU/DevKitC) or ESP32-C3 are top choices thanks to extensive library support, readily available Arduino IDE examples, and thorough documentation.",
|
||||
},
|
||||
{
|
||||
pergunta: "Which ESP32 supports Wi-Fi 6, Bluetooth 6 and Thread/Zigbee/Matter?",
|
||||
resposta: "The ESP32-C6 and ESP32-C5 are the leading series for modern networking. The ESP32-C6 offers 2.4 GHz Wi-Fi 6 and 802.15.4 radio (Zigbee 3.0 / Thread / Matter). The ESP32-C5 is the first to introduce Dual-Band Wi-Fi 6 on both 2.4 GHz and 5 GHz bands simultaneously.",
|
||||
},
|
||||
{
|
||||
pergunta: "Which is the most powerful ESP32 for AI (TinyML) and Displays?",
|
||||
resposta: "The ESP32-P4 (dual-core RISC-V at 400 MHz with AI vector extensions, MIPI-CSI/DSI interfaces, and up to 64 MB PSRAM) and ESP32-S3 (dual-core Xtensa at 240 MHz with neural network vector acceleration and RGB LCD support) provide maximum speed for edge AI and rich graphical interfaces.",
|
||||
},
|
||||
{
|
||||
pergunta: "Which ESP32 consumes the least power for battery-operated projects?",
|
||||
resposta: "Compact RISC-V microcontrollers with ULP coprocessors like the ESP32-C2, ESP32-C3, and ESP32-H2 (dedicated 802.15.4 without Wi-Fi) achieve ultra-low deep sleep currents ranging between 5 µA and 10 µA.",
|
||||
},
|
||||
];
|
||||
|
||||
export default async function Layout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const faqs = isEn ? faqsEn : faqsPt;
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.aplicacaoWeb({
|
||||
nome: isEn ? "Intelligent ESP32 Selector" : "Seletor Inteligente de ESP32",
|
||||
descricao: isEn
|
||||
? "Interactive tool analyzing connectivity, power consumption, peripherals, and security to recommend the ideal ESP32 series."
|
||||
: "Ferramenta interativa que analisa conectividade, consumo, periféricos e segurança para indicar a série ideal de ESP32.",
|
||||
caminho: isEn ? "/en/selector" : "/seletor",
|
||||
locale,
|
||||
})
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: isEn ? "Home" : "Início", caminho: isEn ? "/en" : "/" },
|
||||
{ nome: isEn ? "ESP32 Selector" : "Seletor de ESP32", caminho: isEn ? "/en/selector" : "/seletor" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.perguntas(faqs)),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,629 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import { notFound } from "next/navigation";
|
||||
import seriesDataPt from "@/public/series.json";
|
||||
import seriesDataEn from "@/data/en/series.json";
|
||||
import ConnectionsDiagram from "@/components/ConnectionsDiagram";
|
||||
import SeriesTabMenu from "@/components/SeriesTabMenu";
|
||||
import PinRestrictions from "@/components/PinRestrictions";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
import {
|
||||
AlertTriangle,
|
||||
ArrowLeft,
|
||||
ArrowRight,
|
||||
ArrowUpRight,
|
||||
Battery,
|
||||
BookOpen,
|
||||
Code,
|
||||
Cpu,
|
||||
Database,
|
||||
ExternalLink,
|
||||
FileText,
|
||||
Lightbulb,
|
||||
Package,
|
||||
Scale,
|
||||
ShieldCheck,
|
||||
Sliders,
|
||||
Thermometer,
|
||||
Wifi,
|
||||
} from "lucide-react";
|
||||
|
||||
export default async function SerieDetail({ params }) {
|
||||
const { locale, key } = await params;
|
||||
const isEn = locale === "en";
|
||||
const currentLocale = isEn ? "en" : "pt";
|
||||
const seriesData = isEn ? seriesDataEn : seriesDataPt;
|
||||
const serie = seriesData[key];
|
||||
|
||||
if (!serie) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
let conexoes = [];
|
||||
try {
|
||||
conexoes = isEn ? require(`@/data/en/conexoes/${key}.json`) : require(`@/public/conexoes/${key}.json`);
|
||||
} catch (error) {
|
||||
console.log(`Arquivo de conexões não encontrado para ${key}`);
|
||||
}
|
||||
|
||||
const seriesKeys = Object.keys(seriesData);
|
||||
const currentIndex = seriesKeys.indexOf(key);
|
||||
const previousKey = currentIndex > 0 ? seriesKeys[currentIndex - 1] : null;
|
||||
const nextKey = currentIndex < seriesKeys.length - 1 ? seriesKeys[currentIndex + 1] : null;
|
||||
|
||||
const nao = isEn ? "No" : "Não";
|
||||
const naoInformado = isEn ? "Not informed" : "Não informado";
|
||||
|
||||
const processadorSpecs = isEn
|
||||
? [
|
||||
{ label: "Architecture", value: serie.arquitetura },
|
||||
{ label: "Cores", value: serie.nucleos },
|
||||
{ label: "Frequency", value: serie.frequencia },
|
||||
{ label: "ULP Coprocessor", value: serie.coprocessador_ulp || nao },
|
||||
{ label: "AI Accelerators", value: serie.aceleradores_ia || nao },
|
||||
]
|
||||
: [
|
||||
{ label: "Arquitetura", value: serie.arquitetura },
|
||||
{ label: "Núcleos", value: serie.nucleos },
|
||||
{ label: "Frequência", value: serie.frequencia },
|
||||
{ label: "Coprocessador ULP", value: serie.coprocessador_ulp || "Não" },
|
||||
{ label: "Aceleradores IA", value: serie.aceleradores_ia || "Não" },
|
||||
];
|
||||
|
||||
const seg = serie.seguranca || {};
|
||||
const segurancaSpecs = isEn
|
||||
? [
|
||||
{ label: "AES", value: seg.aes || nao },
|
||||
{ label: "SHA", value: seg.sha || nao },
|
||||
{ label: "RSA / MPI", value: seg.rsa || nao },
|
||||
{ label: "ECC (elliptic curves)", value: seg.ecc || nao },
|
||||
{ label: "Hardware ECDSA", value: seg.ecdsa || nao },
|
||||
{ label: "HMAC", value: seg.hmac || nao },
|
||||
{ label: "Digital Signature (DS)", value: seg.assinatura_digital || nao },
|
||||
{ label: "Key Manager", value: seg.key_manager || nao },
|
||||
{ label: "Random Generator (TRNG)", value: seg.rng || nao },
|
||||
{ label: "Flash Encryption", value: seg.criptografia_flash || nao },
|
||||
{ label: "Secure Boot", value: seg.secure_boot || nao },
|
||||
{ label: "DPA Protection", value: seg.protecao_dpa || nao },
|
||||
]
|
||||
: [
|
||||
{ label: "AES", value: seg.aes || "Não" },
|
||||
{ label: "SHA", value: seg.sha || "Não" },
|
||||
{ label: "RSA / MPI", value: seg.rsa || "Não" },
|
||||
{ label: "ECC (curvas elípticas)", value: seg.ecc || "Não" },
|
||||
{ label: "ECDSA em hardware", value: seg.ecdsa || "Não" },
|
||||
{ label: "HMAC", value: seg.hmac || "Não" },
|
||||
{ label: "Assinatura Digital (DS)", value: seg.assinatura_digital || "Não" },
|
||||
{ label: "Key Manager", value: seg.key_manager || "Não" },
|
||||
{ label: "Gerador aleatório (RNG)", value: seg.rng || "Não" },
|
||||
{ label: "Criptografia de flash", value: seg.criptografia_flash || "Não" },
|
||||
{ label: "Secure Boot", value: seg.secure_boot || "Não" },
|
||||
{ label: "Proteção contra DPA", value: seg.protecao_dpa || "Não" },
|
||||
];
|
||||
|
||||
const ferramentasSpecs = isEn
|
||||
? [
|
||||
{ label: "Minimum ESP-IDF", value: serie.esp_idf_minimo || naoInformado },
|
||||
{ label: "Arduino Core", value: serie.arduino_core || naoInformado },
|
||||
{ label: "Debugging", value: serie.depuracao || naoInformado },
|
||||
{ label: "Package", value: serie.encapsulamento || naoInformado },
|
||||
{ label: "Available Modules", value: serie.modulos || naoInformado },
|
||||
]
|
||||
: [
|
||||
{ label: "ESP-IDF mínimo", value: serie.esp_idf_minimo || "Não informado" },
|
||||
{ label: "Core Arduino", value: serie.arduino_core || "Não informado" },
|
||||
{ label: "Depuração", value: serie.depuracao || "Não informado" },
|
||||
{ label: "Encapsulamento", value: serie.encapsulamento || "Não informado" },
|
||||
{ label: "Módulos disponíveis", value: serie.modulos || "Não informado" },
|
||||
];
|
||||
|
||||
const conectividadeSpecs = isEn
|
||||
? [
|
||||
{ label: "Wi-Fi", value: serie.wifi || nao },
|
||||
{ label: "Bluetooth", value: serie.bluetooth || nao },
|
||||
{ label: "Zigbee/Thread", value: serie.zigbee_thread || nao },
|
||||
{ label: "Matter", value: serie.matter || nao },
|
||||
{ label: "Ethernet", value: serie.ethernet || serie.ethernet_mac || nao },
|
||||
{ label: "CAN", value: serie.can || nao },
|
||||
]
|
||||
: [
|
||||
{ label: "Wi-Fi", value: serie.wifi || "Não" },
|
||||
{ label: "Bluetooth", value: serie.bluetooth || "Não" },
|
||||
{ label: "Zigbee/Thread", value: serie.zigbee_thread || "Não" },
|
||||
{ label: "Matter", value: serie.matter || "Não" },
|
||||
{ label: "Ethernet", value: serie.ethernet || serie.ethernet_mac || "Não" },
|
||||
{ label: "CAN", value: serie.can || "Não" },
|
||||
];
|
||||
|
||||
const memoriaSpecs = isEn
|
||||
? [
|
||||
{ label: "SRAM", value: serie.memoria_sram },
|
||||
{ label: "RTC SRAM", value: serie.memoria_sram_rtc },
|
||||
{ label: "ROM", value: serie.memoria_rom },
|
||||
{ label: "External Flash", value: serie.flash_externa },
|
||||
{ label: "External PSRAM", value: serie.psram_externa || nao },
|
||||
]
|
||||
: [
|
||||
{ label: "SRAM", value: serie.memoria_sram },
|
||||
{ label: "SRAM RTC", value: serie.memoria_sram_rtc },
|
||||
{ label: "ROM", value: serie.memoria_rom },
|
||||
{ label: "Flash Externa", value: serie.flash_externa },
|
||||
{ label: "PSRAM Externa", value: serie.psram_externa || "Não" },
|
||||
];
|
||||
|
||||
const perifericos = isEn
|
||||
? [
|
||||
{ label: "GPIO", value: serie.gpio },
|
||||
{ label: "ADC", value: serie.adc },
|
||||
{ label: "DAC", value: serie.dac || nao },
|
||||
{ label: "Touch", value: serie.touch || nao },
|
||||
{ label: "UART", value: serie.uart },
|
||||
{ label: "SPI", value: serie.spi },
|
||||
{ label: "I2C", value: serie.i2c },
|
||||
{ label: "I2S", value: serie.i2s },
|
||||
{ label: "PWM", value: serie.pwm },
|
||||
{ label: "USB", value: serie.usb || nao },
|
||||
]
|
||||
: [
|
||||
{ label: "GPIO", value: serie.gpio },
|
||||
{ label: "ADC", value: serie.adc },
|
||||
{ label: "DAC", value: serie.dac || "Não" },
|
||||
{ label: "Touch", value: serie.touch || "Não" },
|
||||
{ label: "UART", value: serie.uart },
|
||||
{ label: "SPI", value: serie.spi },
|
||||
{ label: "I2C", value: serie.i2c },
|
||||
{ label: "I2S", value: serie.i2s },
|
||||
{ label: "PWM", value: serie.pwm },
|
||||
{ label: "USB", value: serie.usb || "Não" },
|
||||
];
|
||||
|
||||
const interfacesEspeciais = [];
|
||||
if (serie.lcd) interfacesEspeciais.push({ label: "LCD", value: serie.lcd });
|
||||
if (serie.camera) interfacesEspeciais.push({ label: isEn ? "Camera" : "Câmera", value: serie.camera });
|
||||
if (serie.mipi_csi) interfacesEspeciais.push({ label: "MIPI CSI", value: serie.mipi_csi });
|
||||
if (serie.mipi_dsi) interfacesEspeciais.push({ label: "MIPI DSI", value: serie.mipi_dsi });
|
||||
if (serie.sdio) interfacesEspeciais.push({ label: "SDIO", value: serie.sdio });
|
||||
if (serie.sensor_hall) interfacesEspeciais.push({ label: isEn ? "Hall Sensor" : "Sensor Hall", value: serie.sensor_hall });
|
||||
if (serie.sensor_temperatura) interfacesEspeciais.push({ label: isEn ? "Temperature Sensor" : "Sensor Temperatura", value: serie.sensor_temperatura });
|
||||
|
||||
// Consumo de Energia
|
||||
const consumoEnergia = [];
|
||||
if (serie.consumo_energia) {
|
||||
const modoLabelsPt = {
|
||||
'active': 'Modo Ativo',
|
||||
'active_cpu_240mhz': 'Ativo (CPU 240MHz)',
|
||||
'active_cpu_160mhz': 'Ativo (CPU 160MHz)',
|
||||
'active_wifi_tx': 'Ativo (Wi-Fi TX)',
|
||||
'active_wifi_tx_peak': 'Ativo (Wi-Fi TX Pico)',
|
||||
'active_wifi': 'Ativo (Wi-Fi)',
|
||||
'active_wifi6': 'Ativo (Wi-Fi 6)',
|
||||
'modem_sleep': 'Modem Sleep',
|
||||
'modem_sleep_cpu_160mhz': 'Modem Sleep (CPU 160MHz)',
|
||||
'light_sleep': 'Light Sleep',
|
||||
'deep_sleep': 'Deep Sleep',
|
||||
'hibernation': 'Hibernação'
|
||||
};
|
||||
const modoLabelsEn = {
|
||||
'active': 'Active Mode',
|
||||
'active_cpu_240mhz': 'Active (CPU 240MHz)',
|
||||
'active_cpu_160mhz': 'Active (CPU 160MHz)',
|
||||
'active_wifi_tx': 'Active (Wi-Fi TX)',
|
||||
'active_wifi_tx_peak': 'Active (Wi-Fi TX Peak)',
|
||||
'active_wifi': 'Active (Wi-Fi)',
|
||||
'active_wifi6': 'Active (Wi-Fi 6)',
|
||||
'modem_sleep': 'Modem Sleep',
|
||||
'modem_sleep_cpu_160mhz': 'Modem Sleep (CPU 160MHz)',
|
||||
'light_sleep': 'Light Sleep',
|
||||
'deep_sleep': 'Deep Sleep',
|
||||
'hibernation': 'Hibernation'
|
||||
};
|
||||
const modoLabels = isEn ? modoLabelsEn : modoLabelsPt;
|
||||
|
||||
Object.entries(serie.consumo_energia).forEach(([modo, consumo]) => {
|
||||
consumoEnergia.push({
|
||||
label: modoLabels[modo] || modo.replace(/_/g, ' ').replace(/\b\w/g, (l) => l.toUpperCase()),
|
||||
value: consumo
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
id: "devboard",
|
||||
label: isEn ? "Development board" : "Placa de desenvolvimento",
|
||||
available: serie.placa,
|
||||
content: (
|
||||
<div className="card p-5 sm:p-7">
|
||||
<h2 className="text-lg font-semibold text-ink">
|
||||
{isEn ? "Official development kit" : "Kit de desenvolvimento oficial"}
|
||||
</h2>
|
||||
<div className="mt-5 overflow-hidden rounded-xl border border-line bg-surface-2 p-4">
|
||||
<Image
|
||||
src={serie.placa}
|
||||
alt={isEn ? `Development board ${key}` : `Placa de desenvolvimento ${key}`}
|
||||
width={1200}
|
||||
height={800}
|
||||
className="mx-auto h-auto max-h-[28rem] w-full rounded-lg object-contain"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
<p className="mt-3 text-sm text-muted">
|
||||
{isEn ? (
|
||||
<>Official Espressif board for the {key} series.</>
|
||||
) : (
|
||||
<>Placa padrão da Espressif para a série {key}.</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "connections",
|
||||
label: isEn ? "Pinout diagram" : "Diagrama de conexões",
|
||||
available: conexoes.length > 0,
|
||||
content: (
|
||||
<div className="card p-5 sm:p-7">
|
||||
<div className="callout callout-warn flex items-start gap-3">
|
||||
<AlertTriangle className="mt-0.5 h-5 w-5 shrink-0 text-gold" aria-hidden="true" />
|
||||
<div>
|
||||
<p className="font-semibold text-ink">
|
||||
{isEn ? "This is the chip diagram, not the development board" : "Este é o diagrama do chip, não da placa"}
|
||||
</p>
|
||||
<p className="mt-1">
|
||||
{isEn ? (
|
||||
`The map shows the silicon connections for the ${key}. Each development board exposes only a subset or routes them differently.`
|
||||
) : (
|
||||
<>
|
||||
O mapa mostra as conexões do silício do <strong>{key}</strong>. Cada placa de desenvolvimento
|
||||
expõe só parte delas, ou as roteia de outra forma.
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6">
|
||||
<ConnectionsDiagram connections={conexoes} serie={serie} />
|
||||
</div>
|
||||
|
||||
<div className="callout mt-8">
|
||||
<p className="flex items-center gap-2 font-semibold text-ink">
|
||||
<Lightbulb className="h-4 w-4 text-accent" aria-hidden="true" />
|
||||
{isEn ? "Almost every pin is reconfigurable" : "Quase todo pino é reconfigurável"}
|
||||
</p>
|
||||
<p className="mt-1">
|
||||
{isEn ? (
|
||||
<>
|
||||
The {key} IO matrix allows moving SPI, I2C, UART, PWM, and camera/display buses
|
||||
to most digital pins. For strapping restrictions and analog pins, consult the{" "}
|
||||
<a
|
||||
href={`https://docs.espressif.com/projects/esp-idf/en/latest/${String(key).toLowerCase().replace("-", "")}/api-reference/peripherals/gpio.html`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-1 font-medium text-accent underline decoration-accent/30 underline-offset-2 hover:decoration-accent"
|
||||
>
|
||||
official GPIO guide
|
||||
<ExternalLink className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
</a>
|
||||
.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
A matriz de IO do {key} permite mover SPI, I2C, UART, PWM e barramentos de câmera ou display
|
||||
para a maioria dos pinos digitais. Para as restrições de strapping e dos pinos analógicos,
|
||||
consulte o{" "}
|
||||
<a
|
||||
href={`https://docs.espressif.com/projects/esp-idf/en/latest/${String(key).toLowerCase().replace("-", "")}/api-reference/peripherals/gpio.html`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-1 font-medium text-accent underline decoration-accent/30 underline-offset-2 hover:decoration-accent"
|
||||
>
|
||||
guia oficial de GPIO
|
||||
<ExternalLink className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
</a>
|
||||
.
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const secoes = [
|
||||
{ id: "processador", titulo: isEn ? "Processor" : "Processador", icon: Cpu, specs: processadorSpecs },
|
||||
{ id: "conectividade", titulo: isEn ? "Connectivity" : "Conectividade", icon: Wifi, specs: conectividadeSpecs },
|
||||
{ id: "ferramentas", titulo: isEn ? "Tools and availability" : "Ferramentas e disponibilidade", icon: Package, specs: ferramentasSpecs },
|
||||
{ id: "seguranca", titulo: isEn ? "Security" : "Segurança", icon: ShieldCheck, specs: segurancaSpecs },
|
||||
{ id: "memoria", titulo: isEn ? "Memory" : "Memória", icon: Database, specs: memoriaSpecs },
|
||||
...(consumoEnergia.length > 0
|
||||
? [{
|
||||
id: "energia",
|
||||
titulo: isEn ? "Power consumption" : "Consumo de energia",
|
||||
icon: Battery,
|
||||
specs: consumoEnergia,
|
||||
nota: isEn
|
||||
? "Typical values at 3.3 V and 25 °C. Actual power consumption depends on radio duty cycle and configured clock frequency."
|
||||
: "Valores típicos a 3,3 V e 25 °C. O consumo real depende do ciclo de trabalho do rádio e da frequência de clock configurada.",
|
||||
}]
|
||||
: []),
|
||||
{ id: "perifericos", titulo: isEn ? "Peripherals" : "Periféricos", icon: Sliders, specs: perifericos },
|
||||
...(interfacesEspeciais.length > 0
|
||||
? [{ id: "interfaces", titulo: isEn ? "Special interfaces" : "Interfaces especiais", icon: Sliders, specs: interfacesEspeciais }]
|
||||
: []),
|
||||
{
|
||||
id: "temperatura",
|
||||
titulo: isEn ? "Temperature limits" : "Limites de temperatura",
|
||||
icon: Thermometer,
|
||||
specs: [
|
||||
{ label: isEn ? "Operating" : "Operação", value: serie.temperatura_operacao },
|
||||
{ label: isEn ? "Storage" : "Armazenamento", value: serie.temperatura_armazenamento },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const fatos = [
|
||||
{ label: isEn ? "Processor" : "Processador", value: String(serie.nucleos).includes("2") ? "Dual-core" : "Single-core", detail: serie.frequencia },
|
||||
{ label: "SRAM", value: serie.memoria_sram, detail: isEn ? `+ ${serie.memoria_sram_rtc} RTC SRAM` : `+ ${serie.memoria_sram_rtc} de SRAM RTC` },
|
||||
{ label: "GPIO", value: serie.gpio, detail: isEn ? "programmable pins" : "pinos programáveis" },
|
||||
{ label: isEn ? "Architecture" : "Arquitetura", value: String(serie.arquitetura).includes("RISC-V") ? "RISC-V" : "Xtensa", detail: serie.arquitetura },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.serie(key, serie, currentLocale)) }}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.trilha([
|
||||
{ nome: isEn ? "Home" : "Início", caminho: isEn ? "/en" : "/" },
|
||||
{ nome: isEn ? "Series" : "Séries", caminho: getLocalizedHref("/series", currentLocale) },
|
||||
{ nome: serie.nome_completo, caminho: getLocalizedHref(`/series/${key}`, currentLocale) },
|
||||
])),
|
||||
}}
|
||||
/>
|
||||
|
||||
<Header />
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
isEn={isEn}
|
||||
trail={[{ label: isEn ? "Series" : "Séries", href: getLocalizedHref("/series", currentLocale) }, { label: key }]}
|
||||
icon={Cpu}
|
||||
label={serie.arquitetura}
|
||||
title={key}
|
||||
lede={serie.descricao}
|
||||
>
|
||||
{serie.datasheet ? (
|
||||
<a href={serie.datasheet} target="_blank" rel="noopener noreferrer" className="btn btn-primary">
|
||||
<FileText className="h-4 w-4" aria-hidden="true" />
|
||||
{isEn ? "Official datasheet" : "Datasheet oficial"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
) : (
|
||||
<span className="btn btn-ghost cursor-not-allowed opacity-70" aria-disabled="true">
|
||||
<FileText className="h-4 w-4" aria-hidden="true" />
|
||||
{isEn ? "Datasheet not yet published" : "Datasheet ainda não publicado"}
|
||||
</span>
|
||||
)}
|
||||
{serie.guia_de_programacao && (
|
||||
<a href={serie.guia_de_programacao} target="_blank" rel="noopener noreferrer" className="btn btn-ghost">
|
||||
<Code className="h-4 w-4" aria-hidden="true" />
|
||||
{isEn ? "Programming guide" : "Guia de programação"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
)}
|
||||
{serie.manual_tecnico && (
|
||||
<a href={serie.manual_tecnico} target="_blank" rel="noopener noreferrer" className="btn btn-ghost">
|
||||
<BookOpen className="h-4 w-4" aria-hidden="true" />
|
||||
{isEn ? "Technical reference manual" : "Manual técnico"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
)}
|
||||
</PageHero>
|
||||
|
||||
<section className="shell mt-10" aria-label={isEn ? "Summary" : "Resumo"}>
|
||||
<dl className="grid grid-cols-2 gap-3 lg:grid-cols-4">
|
||||
{fatos.map((fato) => (
|
||||
<div key={fato.label} className="tile">
|
||||
<dt className="text-xs font-medium text-muted">{fato.label}</dt>
|
||||
<dd className="mt-1 font-display text-2xl font-semibold tracking-[-0.03em] text-ink">{fato.value}</dd>
|
||||
<dd className="mt-0.5 text-xs text-muted">{fato.detail}</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
|
||||
{serie.status_documentacao && (
|
||||
<div className="callout callout-warn mt-4 flex items-start gap-3">
|
||||
<AlertTriangle className="mt-0.5 h-5 w-5 shrink-0 text-gold" aria-hidden="true" />
|
||||
<div>
|
||||
<p className="font-semibold text-ink">
|
||||
{isEn ? "Preliminary documentation" : "Documentação preliminar"}
|
||||
</p>
|
||||
<p className="mt-1">{serie.status_documentacao}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
|
||||
<div className="shell mt-10">
|
||||
<SeriesTabMenu tabs={tabs} isEn={isEn} />
|
||||
<PinRestrictions conexoes={conexoes} serieKey={key} isEn={isEn} />
|
||||
</div>
|
||||
|
||||
<div className="shell mt-12">
|
||||
<nav
|
||||
aria-label={isEn ? "Datasheet sections" : "Seções da ficha"}
|
||||
className="nav-pill no-scrollbar sticky top-20 z-30 flex gap-1 overflow-x-auto rounded-full p-1.5"
|
||||
>
|
||||
{secoes.map((secao) => (
|
||||
<a key={secao.id} href={`#${secao.id}`} className="nav-link shrink-0">
|
||||
{secao.titulo}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<div className="mt-8 space-y-5">
|
||||
{secoes.map((secao) => (
|
||||
<SpecSection key={secao.id} {...secao} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section className="shell section">
|
||||
<div className="panel flex flex-col items-start justify-between gap-6 p-7 sm:p-10 md:flex-row md:items-center">
|
||||
<div className="max-w-2xl">
|
||||
<h2 className="section-title">
|
||||
{isEn ? (
|
||||
<>Ready to prototype with {key}?</>
|
||||
) : (
|
||||
<>Pronto para prototipar o {key}?</>
|
||||
)}
|
||||
</h2>
|
||||
<p className="mt-3 text-base text-muted">
|
||||
{isEn
|
||||
? "Explore development boards available for this series, with USB, onboard sensors, and official store links."
|
||||
: "Veja as placas de desenvolvimento disponíveis para a série, com USB, sensores integrados e link para a loja oficial."}
|
||||
</p>
|
||||
</div>
|
||||
<Link href={getLocalizedHref("/catalogo", currentLocale)} className="btn btn-primary shrink-0">
|
||||
{isEn ? "View boards" : "Ver placas"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<nav aria-label={isEn ? "Other series" : "Outras séries"} className="mt-6 grid gap-3 sm:grid-cols-[1fr_auto_1fr] sm:items-center">
|
||||
{previousKey ? (
|
||||
<Link href={getLocalizedHref(`/series/${previousKey}`, currentLocale)} className="card card-interactive group flex items-center gap-3 px-5 py-4">
|
||||
<ArrowLeft className="h-4 w-4 text-muted transition-transform group-hover:-translate-x-1" aria-hidden="true" />
|
||||
<span>
|
||||
<span className="block text-xs text-muted">{isEn ? "Previous series" : "Série anterior"}</span>
|
||||
<span className="block font-display text-lg font-semibold text-ink">{previousKey}</span>
|
||||
</span>
|
||||
</Link>
|
||||
) : (
|
||||
<span className="hidden sm:block" />
|
||||
)}
|
||||
<Link href={getLocalizedHref("/comparacao", currentLocale)} className="btn btn-ghost justify-self-center">
|
||||
<Scale className="h-4 w-4" aria-hidden="true" />
|
||||
{isEn ? "Compare series" : "Comparar séries"}
|
||||
</Link>
|
||||
{nextKey ? (
|
||||
<Link href={getLocalizedHref(`/series/${nextKey}`, currentLocale)} className="card card-interactive group flex items-center justify-end gap-3 px-5 py-4 text-right">
|
||||
<span>
|
||||
<span className="block text-xs text-muted">{isEn ? "Next series" : "Próxima série"}</span>
|
||||
<span className="block font-display text-lg font-semibold text-ink">{nextKey}</span>
|
||||
</span>
|
||||
<ArrowRight className="h-4 w-4 text-muted transition-transform group-hover:translate-x-1" aria-hidden="true" />
|
||||
</Link>
|
||||
) : (
|
||||
<span className="hidden sm:block" />
|
||||
)}
|
||||
</nav>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SpecSection({ id, titulo, icon: Icon, specs, nota }) {
|
||||
return (
|
||||
<section id={id} aria-labelledby={`${id}-titulo`} className="card scroll-mt-36 p-5 sm:p-7">
|
||||
<h2 id={`${id}-titulo`} className="flex items-center gap-3 font-display text-xl font-semibold tracking-[-0.03em] text-ink">
|
||||
<span className="grid h-9 w-9 place-items-center rounded-full bg-accent-soft text-accent">
|
||||
<Icon className="h-4 w-4" aria-hidden="true" />
|
||||
</span>
|
||||
{titulo}
|
||||
</h2>
|
||||
{nota && <p className="mt-3 text-sm text-muted">{nota}</p>}
|
||||
<dl className="mt-5 grid grid-cols-2 gap-3 lg:grid-cols-3">
|
||||
{specs.map((spec) => {
|
||||
const negativo = /^n[ãa]o\b|^no\b/i.test(String(spec.value));
|
||||
return (
|
||||
<div key={spec.label} className="tile">
|
||||
<dt className="text-xs font-medium text-muted">{spec.label}</dt>
|
||||
<dd className={`mt-1 text-sm font-semibold leading-snug ${negativo ? "text-muted" : "text-ink"}`}>{spec.value}</dd>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</dl>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale, key } = await params;
|
||||
const isEn = locale === "en";
|
||||
const currentLocale = isEn ? "en" : "pt";
|
||||
const seriesData = isEn ? seriesDataEn : seriesDataPt;
|
||||
const serie = seriesData[key];
|
||||
|
||||
if (!serie) {
|
||||
return { title: isEn ? "Series not found" : "Série não encontrada", robots: { index: false, follow: false } };
|
||||
}
|
||||
|
||||
const radio = [
|
||||
String(serie.wifi).startsWith("Não") || String(serie.wifi).startsWith("No") ? null : serie.wifi.split(" (")[0],
|
||||
String(serie.bluetooth).startsWith("Não") || String(serie.bluetooth).startsWith("No") ? null : serie.bluetooth.split(" (")[0],
|
||||
serie.zigbee_thread && !String(serie.zigbee_thread).startsWith("Não") && !String(serie.zigbee_thread).startsWith("No") ? "802.15.4" : null,
|
||||
].filter(Boolean).join(", ");
|
||||
|
||||
const descricao = isEn
|
||||
? `${serie.nome_completo}: ${serie.arquitetura}, ${serie.frequencia}, ` +
|
||||
`${serie.memoria_sram} SRAM, and ${serie.gpio} GPIOs` +
|
||||
(radio ? `. Radio: ${radio}` : "") +
|
||||
`. Complete pinout, peripherals, hardware security, and restricted pins in English.`
|
||||
: `${serie.nome_completo}: ${serie.arquitetura}, ${serie.frequencia.replace("Até ", "até ")}, ` +
|
||||
`${serie.memoria_sram} de SRAM e ${serie.gpio} GPIOs` +
|
||||
(radio ? `. Rádio: ${radio}` : "") +
|
||||
`. Pinagem completa, periféricos, segurança em hardware e pinos com restrição, em português.`;
|
||||
|
||||
const imagem = serie.placa
|
||||
? [{ url: serie.placa, width: 1600, height: 1091, alt: isEn ? `Pinout of ${serie.nome_completo}` : `Pinagem do ${serie.nome_completo}` }]
|
||||
: [{ url: "/opengraph-image.png", width: 1200, height: 630, alt: "ESPDocs" }];
|
||||
|
||||
const keywords = isEn
|
||||
? [
|
||||
serie.nome_completo, `${serie.nome_completo} pinout`,
|
||||
`${serie.nome_completo} datasheet`, `${serie.nome_completo} specifications`,
|
||||
"ESP32", "Espressif", "microcontroller",
|
||||
]
|
||||
: [
|
||||
serie.nome_completo, `${serie.nome_completo} pinout`,
|
||||
`${serie.nome_completo} datasheet`, `${serie.nome_completo} especificações`,
|
||||
`${serie.nome_completo} português`, "ESP32", "Espressif", "microcontrolador",
|
||||
];
|
||||
|
||||
const meta = {
|
||||
...paginaMeta({
|
||||
titulo: isEn ? `${serie.nome_completo}: specifications and pinout` : `${serie.nome_completo}: especificações e pinagem`,
|
||||
descricao,
|
||||
caminho: `/series/${key}`,
|
||||
tipo: "article",
|
||||
locale: currentLocale,
|
||||
keywords,
|
||||
}),
|
||||
other: { "article:section": isEn ? "ESP32 Series" : "Séries ESP32" },
|
||||
};
|
||||
|
||||
meta.openGraph = { ...meta.openGraph, images: imagem };
|
||||
meta.twitter = { ...meta.twitter, images: imagem };
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return Object.keys(seriesDataPt).map((key) => ({
|
||||
key: key,
|
||||
}));
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const meta = paginaMeta({
|
||||
titulo: isEn ? "ESP32 Series: Technical Guide and Pinouts" : "Séries ESP32",
|
||||
descricao: isEn
|
||||
? "All 12 ESP32 series side by side: ESP32, S2, S3, S31, C2, C3, C5, C6, C61, P4, H2 and H4. Architecture, memory, radio, peripherals and pinouts for each one."
|
||||
: "As 12 séries de ESP32 lado a lado: ESP32, S2, S3, S31, C2, C3, C5, C6, C61, P4, H2 e H4. Arquitetura, memória, rádio, periféricos e pinagem de cada uma, em português.",
|
||||
caminho: "/series",
|
||||
locale,
|
||||
keywords: isEn
|
||||
? ["ESP32 series", "ESP32 models", "ESP32 S3", "ESP32 C6", "ESP32 P4", "difference between ESP32"]
|
||||
: ["séries ESP32", "modelos de ESP32", "ESP32 S3", "ESP32 C6", "ESP32 P4", "diferença entre ESP32"],
|
||||
});
|
||||
meta.title = {
|
||||
default: isEn ? "ESP32 Series" : "Séries ESP32",
|
||||
template: "%s · ESPDocs",
|
||||
};
|
||||
return meta;
|
||||
}
|
||||
|
||||
const faqsPt = [
|
||||
{
|
||||
pergunta: "Quantas séries de ESP32 existem atualmente?",
|
||||
resposta: "Atualmente o ecossistema Espressif conta com 12 séries principais: ESP32 clássico, ESP32-S2, ESP32-S3, ESP32-S31, ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-P4, ESP32-H2 e ESP32-H4.",
|
||||
},
|
||||
{
|
||||
pergunta: "Quais são as séries mais recentes da Espressif?",
|
||||
resposta: "As séries mais recentes incluem o ESP32-P4 (focado em alto desempenho com dual-core RISC-V a 400 MHz), o ESP32-C5 (primeiro chip com Wi-Fi dual-band 2.4/5 GHz da Espressif) e o ESP32-C61 (Wi-Fi 6 e Bluetooth 6 de baixo custo).",
|
||||
},
|
||||
];
|
||||
|
||||
const faqsEn = [
|
||||
{
|
||||
pergunta: "How many ESP32 series currently exist?",
|
||||
resposta: "Currently, the Espressif ecosystem features 12 primary series: classic ESP32, ESP32-S2, ESP32-S3, ESP32-S31, ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-P4, ESP32-H2, and ESP32-H4.",
|
||||
},
|
||||
{
|
||||
pergunta: "What are the latest series from Espressif?",
|
||||
resposta: "The newest series include the ESP32-P4 (high-performance dual-core RISC-V at 400 MHz), the ESP32-C5 (first dual-band 2.4/5 GHz Wi-Fi chip from Espressif), and the ESP32-C61 (cost-effective Wi-Fi 6 and Bluetooth 6).",
|
||||
},
|
||||
];
|
||||
|
||||
export default async function Layout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const faqs = isEn ? faqsEn : faqsPt;
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: isEn ? "Home" : "Início", caminho: isEn ? "/en" : "/" },
|
||||
{ nome: isEn ? "ESP32 Series" : "Séries ESP32", caminho: isEn ? "/en/series" : "/series" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.perguntas(faqs)),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
"use client";
|
||||
|
||||
import { useMemo, useState } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import Link from "next/link";
|
||||
import seriesDataPt from "@/public/series.json";
|
||||
import seriesDataEn from "@/data/en/series.json";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
import {
|
||||
AlertTriangle,
|
||||
ArrowRight,
|
||||
ArrowUpRight,
|
||||
Compass,
|
||||
Home,
|
||||
Scale,
|
||||
ShieldCheck,
|
||||
Sparkles,
|
||||
} from "lucide-react";
|
||||
|
||||
const FILTROS_PT = [
|
||||
{ id: "todas", rotulo: "Todas", testa: () => true },
|
||||
{ id: "riscv", rotulo: "RISC-V", testa: (s) => s.arquitetura.includes("RISC-V") },
|
||||
{ id: "xtensa", rotulo: "Xtensa", testa: (s) => !s.arquitetura.includes("RISC-V") },
|
||||
{ id: "matter", rotulo: "Matter", testa: (s) => s.matter === "Sim" },
|
||||
{ id: "ia", rotulo: "Aceleração de IA", testa: (s) => Boolean(s.aceleradores_ia) },
|
||||
];
|
||||
|
||||
const FILTROS_EN = [
|
||||
{ id: "todas", rotulo: "All", testa: () => true },
|
||||
{ id: "riscv", rotulo: "RISC-V", testa: (s) => s.arquitetura.includes("RISC-V") },
|
||||
{ id: "xtensa", rotulo: "Xtensa", testa: (s) => !s.arquitetura.includes("RISC-V") },
|
||||
{ id: "matter", rotulo: "Matter", testa: (s) => s.matter === "Yes" || s.matter === "Sim" },
|
||||
{ id: "ia", rotulo: "AI Acceleration", testa: (s) => Boolean(s.aceleradores_ia) },
|
||||
];
|
||||
|
||||
/** Marcador de segurança: o recurso que diferencia a série, não o que todas têm. */
|
||||
function nivelSeguranca(serie, isEn) {
|
||||
const seg = serie.seguranca || {};
|
||||
if (seg.key_manager === "Sim" || seg.key_manager === "Yes") return "Key Manager";
|
||||
if (String(seg.ecdsa).startsWith("Sim") || String(seg.ecdsa).startsWith("Yes")) {
|
||||
return isEn ? "Hardware ECDSA" : "ECDSA em hardware";
|
||||
}
|
||||
if (String(seg.ecc).startsWith("Sim") || String(seg.ecc).startsWith("Yes")) {
|
||||
return isEn ? "Hardware ECC" : "ECC em hardware";
|
||||
}
|
||||
if (String(seg.aes).startsWith("AES")) return "AES + SHA";
|
||||
return isEn ? "SHA only" : "Só SHA";
|
||||
}
|
||||
|
||||
const simPt = (v) => !String(v).includes("Não");
|
||||
const simEn = (v) => !String(v).includes("No") && !String(v).includes("Não");
|
||||
|
||||
export default function Series() {
|
||||
const pathname = usePathname();
|
||||
const isEn = pathname?.startsWith("/en");
|
||||
const currentLocale = isEn ? "en" : "pt";
|
||||
const seriesData = isEn ? seriesDataEn : seriesDataPt;
|
||||
const filtros = isEn ? FILTROS_EN : FILTROS_PT;
|
||||
|
||||
const [filtro, setFiltro] = useState("todas");
|
||||
const todas = Object.entries(seriesData);
|
||||
const ativo = filtros.find((f) => f.id === filtro) || filtros[0];
|
||||
const series = useMemo(() => todas.filter(([, s]) => ativo.testa(s)), [todas, ativo]);
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
<Header />
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
isEn={isEn}
|
||||
trail={[{ label: isEn ? "Series" : "Séries" }]}
|
||||
icon={Compass}
|
||||
label={isEn ? `${todas.length} Espressif families` : `${todas.length} famílias da Espressif`}
|
||||
title={isEn ? "ESP32 Series" : "Séries ESP32"}
|
||||
lede={
|
||||
isEn
|
||||
? "Each series was designed for a specific project type, from battery-powered sensors to AI accelerators. Open the sheet to see pinout, peripherals, and security."
|
||||
: "Cada série foi desenhada para um tipo de projeto, do sensor a bateria ao acelerador de IA. Abra a ficha para ver pinagem, periféricos e segurança."
|
||||
}
|
||||
/>
|
||||
|
||||
<section className="shell pt-10 sm:pt-12" aria-label={isEn ? "Series list" : "Lista de séries"}>
|
||||
<div role="group" aria-label={isEn ? "Filter series" : "Filtrar séries"} className="flex flex-wrap gap-2">
|
||||
{filtros.map((f) => (
|
||||
<button key={f.id} type="button" aria-pressed={filtro === f.id} onClick={() => setFiltro(f.id)} className="chip-btn">
|
||||
{f.rotulo}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<p role="status" aria-live="polite" className="mt-4 text-sm text-muted">
|
||||
{series.length} {series.length === 1 ? (isEn ? "series" : "série") : (isEn ? "series" : "séries")}
|
||||
</p>
|
||||
|
||||
<div className="mt-4 grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{series.map(([key, serie]) => {
|
||||
const riscv = serie.arquitetura.includes("RISC-V");
|
||||
const fatos = isEn
|
||||
? [
|
||||
["Cores", serie.nucleos],
|
||||
["Frequency", serie.frequencia],
|
||||
["SRAM", serie.memoria_sram],
|
||||
["Wi-Fi", simEn(serie.wifi) ? "Yes" : "No"],
|
||||
["Bluetooth", String(serie.bluetooth).includes("No") || String(serie.bluetooth).includes("Não") ? "No" : "Yes"],
|
||||
serie.consumo_energia?.deep_sleep ? ["Deep sleep", serie.consumo_energia.deep_sleep] : null,
|
||||
].filter(Boolean)
|
||||
: [
|
||||
["Núcleos", serie.nucleos],
|
||||
["Frequência", serie.frequencia],
|
||||
["SRAM", serie.memoria_sram],
|
||||
["Wi-Fi", simPt(serie.wifi) ? "Sim" : "Não"],
|
||||
["Bluetooth", serie.bluetooth === "Não" ? "Não" : "Sim"],
|
||||
serie.consumo_energia?.deep_sleep ? ["Deep sleep", serie.consumo_energia.deep_sleep] : null,
|
||||
].filter(Boolean);
|
||||
return (
|
||||
<Link key={key} href={getLocalizedHref(`/series/${key}`, currentLocale)} className="card card-interactive group flex flex-col p-5 sm:p-6">
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<h2 className="font-display text-2xl font-semibold tracking-[-0.03em] text-ink">{key}</h2>
|
||||
<span className="chip">{riscv ? "RISC-V" : "Xtensa"}</span>
|
||||
</div>
|
||||
<p className="mt-2 line-clamp-2 min-h-[2.9rem] text-sm leading-relaxed text-muted">{serie.descricao}</p>
|
||||
|
||||
<dl className="mt-5 divide-y divide-line border-y border-line text-sm">
|
||||
{fatos.map(([rotulo, valor]) => (
|
||||
<div key={rotulo} className="flex items-baseline justify-between gap-4 py-2">
|
||||
<dt className="text-muted">{rotulo}</dt>
|
||||
<dd className={`text-right font-medium ${valor === "Não" || valor === "No" ? "text-muted" : "text-ink"}`}>{valor}</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
|
||||
<ul className="mt-4 flex flex-1 flex-wrap content-start gap-1.5">
|
||||
{serie.aceleradores_ia && (
|
||||
<li className="chip chip-accent">
|
||||
<Sparkles className="h-3 w-3" aria-hidden="true" />
|
||||
{isEn ? "AI Accelerators" : "Aceleradores de IA"}
|
||||
</li>
|
||||
)}
|
||||
<li className="chip">
|
||||
<ShieldCheck className="h-3 w-3 text-accent" aria-hidden="true" />
|
||||
{nivelSeguranca(serie, isEn)}
|
||||
</li>
|
||||
{(serie.matter === "Sim" || serie.matter === "Yes") && (
|
||||
<li className="chip">
|
||||
<Home className="h-3 w-3 text-accent" aria-hidden="true" />
|
||||
Matter
|
||||
</li>
|
||||
)}
|
||||
{serie.status_documentacao && (
|
||||
<li className="chip">
|
||||
<AlertTriangle className="h-3 w-3 text-gold" aria-hidden="true" />
|
||||
{isEn ? "Preliminary documentation" : "Documentação preliminar"}
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
|
||||
<span className="mt-5 inline-flex items-center gap-1 text-sm font-medium text-accent">
|
||||
{isEn ? "Open datasheet" : "Abrir ficha"}
|
||||
<ArrowUpRight className="h-4 w-4 transition-transform group-hover:-translate-y-0.5 group-hover:translate-x-0.5" aria-hidden="true" />
|
||||
</span>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="shell section">
|
||||
<div className="panel flex flex-col items-start justify-between gap-6 p-7 sm:p-10 md:flex-row md:items-center">
|
||||
<div className="max-w-2xl">
|
||||
<h2 className="section-title">
|
||||
{isEn ? "Unsure between two series?" : "Ficou em dúvida entre duas séries?"}
|
||||
</h2>
|
||||
<p className="mt-3 text-base text-muted">
|
||||
{isEn
|
||||
? "The comparator tool puts up to four models side by side: cores, radio, memory, peripherals, and security."
|
||||
: "O comparador coloca até quatro modelos lado a lado: núcleos, rádio, memória, periféricos e segurança."}
|
||||
</p>
|
||||
</div>
|
||||
<Link href={getLocalizedHref("/comparacao", currentLocale)} className="btn btn-primary shrink-0">
|
||||
<Scale className="h-4 w-4" aria-hidden="true" />
|
||||
{isEn ? "Compare series" : "Comparar séries"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
import { paginaMeta, jsonLd, SITE } from "@/lib/seo";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import Image from "next/image";
|
||||
import GiteaMark from "@/components/GiteaMark";
|
||||
import { ArrowUpRight, Code, Globe, GitCompare, Info, Languages } from "lucide-react";
|
||||
|
||||
const REPOSITORIO = SITE.repositorio;
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
return paginaMeta({
|
||||
titulo: isEn ? "About the Project" : "Sobre o projeto",
|
||||
descricao: isEn
|
||||
? "ESPDocs is an independent platform organizing technical documentation of the ESP32 ecosystem. Learn about the project and how to contribute."
|
||||
: "O ESPDocs é uma plataforma independente que reúne a documentação do ecossistema ESP32 em português brasileiro. Saiba como o projeto nasceu e como contribuir.",
|
||||
caminho: "/sobre",
|
||||
keywords: isEn
|
||||
? ["ESPDocs", "ESP32 documentation", "open source ESP32 project"]
|
||||
: ["ESPDocs", "documentação ESP32 português", "projeto open source ESP32"],
|
||||
locale,
|
||||
});
|
||||
}
|
||||
|
||||
export default async function Sobre({ params }) {
|
||||
const { locale } = await params;
|
||||
const isPt = locale === "pt";
|
||||
|
||||
const featuresPt = [
|
||||
{ icon: Languages, title: "Em português", desc: "Dados técnicos organizados e apresentados em português do Brasil." },
|
||||
{ icon: GitCompare, title: "Comparações visuais", desc: "Tabelas e diagramas para escolher a série certa sem abrir dez datasheets." },
|
||||
{ icon: Globe, title: "Acesso centralizado", desc: "Links diretos para a documentação oficial, repositórios e exemplos." },
|
||||
{ icon: Code, title: "Código aberto", desc: "Contribuições são bem-vindas no Gitea." },
|
||||
];
|
||||
|
||||
const featuresEn = [
|
||||
{ icon: Languages, title: "Curated Content", desc: "Structured technical data presented clearly without datasheet noise." },
|
||||
{ icon: GitCompare, title: "Visual comparisons", desc: "Tables and diagrams to select the right series without opening ten datasheets." },
|
||||
{ icon: Globe, title: "Centralized access", desc: "Direct links to official documentation, repositories and examples." },
|
||||
{ icon: Code, title: "Open source", desc: "Contributions are welcome on Gitea." },
|
||||
];
|
||||
|
||||
const features = isPt ? featuresPt : featuresEn;
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
{/* Metadados E-E-A-T de autoria e organização para o Google */}
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.paginaSobre(locale)) }}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: isPt ? "Início" : "Home", caminho: isPt ? "/" : "/en" },
|
||||
{ nome: isPt ? "Sobre o Projeto" : "About the Project", caminho: isPt ? "/sobre" : "/en/about" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
<Header />
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
isEn={!isPt}
|
||||
trail={[{ label: isPt ? "Sobre" : "About" }]}
|
||||
icon={Info}
|
||||
label={isPt ? "Projeto independente" : "Independent project"}
|
||||
title={isPt ? "Sobre o ESPDocs" : "About ESPDocs"}
|
||||
lede={
|
||||
isPt
|
||||
? "Uma plataforma não oficial, em português, que organiza as informações técnicas do ESP32 e leva você à documentação oficial da Espressif. Feita para a comunidade de hardware livre."
|
||||
: "An unofficial platform organizing technical information about the ESP32 and linking directly to official Espressif documentation. Built for the open hardware community."
|
||||
}
|
||||
>
|
||||
<a href={REPOSITORIO} target="_blank" rel="noopener noreferrer" className="btn btn-primary">
|
||||
<GiteaMark className="h-4 w-4" />
|
||||
{isPt ? "Ver o repositório" : "View repository"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</PageHero>
|
||||
|
||||
<div className="shell section grid grid-cols-1 gap-10 pt-12 sm:pt-16 lg:grid-cols-[1fr_22rem] lg:gap-14">
|
||||
<div className="min-w-0 max-w-3xl space-y-12">
|
||||
<section aria-labelledby="missao">
|
||||
<h2 id="missao" className="section-title">{isPt ? "Missão" : "Mission"}</h2>
|
||||
<p className="mt-4 text-base leading-relaxed text-muted">
|
||||
{isPt
|
||||
? "Facilitar o acesso e a compreensão do ecossistema ESP32 com uma interface em português que organiza especificações, compara séries, apresenta frameworks e centraliza os links da documentação oficial. O objetivo é economizar o seu tempo no desenvolvimento de firmware e IoT."
|
||||
: "Facilitate access and understanding of the ESP32 ecosystem with an interface organizing specifications, comparing series, presenting frameworks and centralizing links to official documentation. The goal is to save development time in firmware and IoT projects."}
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="porque">
|
||||
<h2 id="porque" className="section-title">{isPt ? "Por que o ESPDocs existe" : "Why ESPDocs exists"}</h2>
|
||||
<p className="mt-4 text-base leading-relaxed text-muted">
|
||||
{isPt
|
||||
? "As informações sobre os ESP32 costumam estar espalhadas entre datasheets densos, manuais de referência (TRM) e repositórios secundários, tudo em inglês. O ESPDocs condensa e estrutura esses dados para a triagem rápida, antes de você aprofundar na engenharia oficial."
|
||||
: "Information regarding the ESP32 is often scattered across dense datasheets, Technical Reference Manuals (TRM), and secondary repositories. ESPDocs condenses and structures this data for rapid evaluation before diving into in-depth engineering documentation."}
|
||||
</p>
|
||||
<ul className="mt-6 grid gap-3 sm:grid-cols-2">
|
||||
{features.map(({ icon: Icon, title, desc }) => (
|
||||
<li key={title} className="card flex items-start gap-4 p-5">
|
||||
<span className="grid h-10 w-10 shrink-0 place-items-center rounded-full bg-accent-soft text-accent">
|
||||
<Icon className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<div>
|
||||
<h3 className="font-semibold text-ink">{title}</h3>
|
||||
<p className="mt-1 text-sm leading-relaxed text-muted">{desc}</p>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="contribuir">
|
||||
<h2 id="contribuir" className="section-title">{isPt ? "Como contribuir" : "How to contribute"}</h2>
|
||||
<p className="mt-4 text-base leading-relaxed text-muted">
|
||||
{isPt
|
||||
? "Correções de tradução, ajustes em tabelas e novos exemplos de código são muito bem-vindos. O projeto cresce com a comunidade."
|
||||
: "Translation fixes, table refinements and new code examples are welcome. The project grows with the community."}
|
||||
</p>
|
||||
<ol className="mt-6 space-y-3">
|
||||
{(isPt
|
||||
? [
|
||||
"Faça o fork do repositório no Gitea.",
|
||||
"Implemente as melhorias e confira as referências técnicas oficiais.",
|
||||
"Abra um Pull Request descrevendo os ajustes feitos.",
|
||||
]
|
||||
: [
|
||||
"Fork the repository on Gitea.",
|
||||
"Implement improvements and verify official technical references.",
|
||||
"Open a Pull Request describing the changes.",
|
||||
]
|
||||
).map((passo, i) => (
|
||||
<li key={passo} className="card flex items-center gap-4 px-5 py-4">
|
||||
<span className="grid h-8 w-8 shrink-0 place-items-center rounded-full bg-ink text-sm font-semibold text-canvas" aria-hidden="true">
|
||||
{i + 1}
|
||||
</span>
|
||||
<span className="text-sm text-ink-soft sm:text-base">{passo}</span>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="acessibilidade">
|
||||
<h2 id="acessibilidade" className="section-title">{isPt ? "Acessibilidade" : "Accessibility"}</h2>
|
||||
<p className="mt-4 text-base leading-relaxed text-muted">
|
||||
{isPt
|
||||
? "O ESPDocs prioriza a legibilidade, o contraste alto (nível AAA da WCAG) e a navegação completa por teclado. Se encontrar alguma barreira de leitura ou navegação, abra uma issue no repositório."
|
||||
: "ESPDocs prioritizes readability, high contrast (WCAG AAA level), and full keyboard navigation. If you encounter any accessibility or navigation hurdles, please open an issue in the repository."}
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<aside className="space-y-5 lg:sticky lg:top-28 lg:self-start" aria-label={isPt ? "Autor e aviso legal" : "Author and legal notice"}>
|
||||
<div className="panel p-6 sm:p-7">
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="grid h-16 w-16 shrink-0 place-items-center rounded-2xl border border-line bg-white">
|
||||
<Image src="/logo.png" alt="" aria-hidden="true" width={48} height={48} className="h-12 w-12 object-contain" />
|
||||
</span>
|
||||
<div>
|
||||
<h2 className="font-display text-lg font-semibold text-ink">Lucas Rayan Guerra</h2>
|
||||
<p className="text-sm text-muted">{isPt ? "Criador do Ciência Embarcada" : "Creator of Ciência Embarcada"}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 space-y-3 text-sm leading-relaxed text-muted">
|
||||
{isPt ? (
|
||||
<>
|
||||
<p>
|
||||
Técnico em Desenvolvimento de Sistemas, estudante de Ciência da Computação na UFRPE e pesquisador de
|
||||
Blockchain e Criptografia.
|
||||
</p>
|
||||
<p>
|
||||
Diretor de Software na Semine AgriTech e palestrante em eventos como o REC'n'Play, compartilha
|
||||
conteúdo sobre hardware, IoT e cibersegurança.
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p>
|
||||
Systems development technician, Computer Science student at UFRPE, and researcher in Blockchain and Cryptography.
|
||||
</p>
|
||||
<p>
|
||||
Software Director at Semine AgriTech and speaker at events like REC'n'Play, sharing insights on hardware, IoT, and cybersecurity.
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<a href="https://cienciaembarcada.com.br" target="_blank" rel="noopener noreferrer" className="btn btn-ghost mt-6 w-full">
|
||||
{isPt ? "Visitar o Ciência Embarcada" : "Visit Ciência Embarcada"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="callout callout-warn">
|
||||
<p className="font-semibold text-ink">{isPt ? "Aviso legal" : "Legal notice"}</p>
|
||||
<p className="mt-1">
|
||||
{isPt
|
||||
? "O ESPDocs é um agregador e organizador. Os manuais e repositórios referenciados pertencem à Espressif Systems. Em projetos críticos ou comerciais, consulte sempre a documentação oficial."
|
||||
: "ESPDocs is an aggregator and curation platform. Referenced manuals and repositories are property of Espressif Systems. In mission-critical or commercial designs, always consult official documentation."}
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { construirIndiceBusca } from "@/lib/searchIndex";
|
||||
|
||||
export const dynamic = "force-static";
|
||||
|
||||
export function generateStaticParams() {
|
||||
return [{ locale: "pt" }, { locale: "en" }];
|
||||
}
|
||||
|
||||
export async function GET(request, { params }) {
|
||||
const { locale } = await params;
|
||||
const loc = locale === "en" ? "en" : "pt";
|
||||
return Response.json(construirIndiceBusca(loc), {
|
||||
headers: {
|
||||
"Cache-Control": "no-cache, no-store, must-revalidate",
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export const metadata = paginaMeta({
|
||||
titulo: "Catálogo de placas ESP32",
|
||||
descricao: "Placas de desenvolvimento com ESP32 disponíveis no Brasil, com filtro por série, conector e conversor USB-serial.",
|
||||
caminho: "/catalogo",
|
||||
keywords: ["placas ESP32", "DevKit ESP32", "comprar ESP32", "ESP32 DevKitC"],
|
||||
});
|
||||
|
||||
export default function Layout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.aplicacaoWeb({
|
||||
nome: "Catálogo de Placas ESP32",
|
||||
descricao: "Guia e catálogo interativo de placas de desenvolvimento e DevKits com microcontroladores ESP32.",
|
||||
caminho: "/catalogo",
|
||||
})
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Catálogo de Placas", caminho: "/catalogo" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export const metadata = paginaMeta({
|
||||
titulo: "Comparar séries ESP32",
|
||||
descricao: "Compare até quatro séries de ESP32 lado a lado: processador, Wi-Fi, Bluetooth, memória, GPIO, periféricos e segurança em hardware, com os dados dos datasheets oficiais.",
|
||||
caminho: "/comparacao",
|
||||
keywords: ["comparar ESP32", "ESP32 vs ESP32-S3", "tabela comparativa ESP32", "qual ESP32 é melhor"],
|
||||
});
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
pergunta: "Como comparar microcontroladores ESP32 lado a lado?",
|
||||
resposta: "O comparador do ESPDocs permite selecionar até quatro séries simultaneamente para confrontar arquitetura, frequência de clock, memória SRAM/PSRAM, padrões de rádio (Wi-Fi 4/6, Bluetooth 5/6, 802.15.4), interfaces de periféricos e blocos de segurança em hardware.",
|
||||
},
|
||||
{
|
||||
pergunta: "Qual a diferença entre o ESP32 clássico e o ESP32-S3?",
|
||||
resposta: "O ESP32 clássico usa núcleos Xtensa LX6 e Bluetooth clássico/LE. O ESP32-S3 traz núcleos Xtensa LX7 com instruções vetoriais para inteligência artificial (TinyML), USB nativo OTG, mais GPIOs (45 contra 36) e Bluetooth 5.0 LE.",
|
||||
},
|
||||
{
|
||||
pergunta: "Qual a diferença entre ESP32-C3 e ESP32-C6?",
|
||||
resposta: "O ESP32-C3 é um microcontrolador RISC-V com Wi-Fi 4 e Bluetooth 5 LE. O ESP32-C6 evolui para Wi-Fi 6 (802.11ax), Bluetooth 5.4 LE, rádio IEEE 802.15.4 para Zigbee 3.0 e Thread 1.3, além de coprocessador de ultrabaixo consumo.",
|
||||
},
|
||||
];
|
||||
|
||||
export default function Layout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.aplicacaoWeb({
|
||||
nome: "Comparador de Séries ESP32",
|
||||
descricao: "Tabela comparativa técnica para analisar especificações, pinagens e recursos de múltiplas séries de ESP32.",
|
||||
caminho: "/comparacao",
|
||||
})
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Comparar Séries", caminho: "/comparacao" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.perguntas(faqs)),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import { useEffect, useState, Fragment } from "react";
|
||||
import Link from "next/link";
|
||||
import seriesData from "@/public/series.json";
|
||||
import { ArrowRight, ArrowUpRight, Check, ChevronDown, Scale } from "lucide-react";
|
||||
|
||||
const MIN_SERIES = 2;
|
||||
const MAX_SERIES = 4;
|
||||
|
||||
/* Lê "seguranca.ecc" além de chaves simples. */
|
||||
function valorDe(objeto, caminho) {
|
||||
return caminho.split(".").reduce((atual, parte) => atual?.[parte], objeto);
|
||||
}
|
||||
|
||||
export default function Comparacao() {
|
||||
const [selectedSeries, setSelectedSeries] = useState(["ESP32", "ESP32-S3"]);
|
||||
const [soDiferencas, setSoDiferencas] = useState(false);
|
||||
const [collapsedCategories, setCollapsedCategories] = useState({
|
||||
"Interfaces Especiais": true,
|
||||
"Especificações Ambientais": true,
|
||||
});
|
||||
|
||||
const series = Object.entries(seriesData);
|
||||
|
||||
// O seletor envia as séries finalistas em ?chips=ESP32-S3,ESP32-C6.
|
||||
useEffect(() => {
|
||||
const chips = new URLSearchParams(window.location.search).get("chips");
|
||||
if (!chips) return;
|
||||
const validas = [...new Set(chips.split(","))].filter((k) => seriesData[k]).slice(0, MAX_SERIES);
|
||||
if (validas.length >= MIN_SERIES) setSelectedSeries(validas);
|
||||
}, []);
|
||||
|
||||
const toggleSeries = (seriesKey) => {
|
||||
if (selectedSeries.includes(seriesKey)) {
|
||||
if (selectedSeries.length > MIN_SERIES) setSelectedSeries(selectedSeries.filter((s) => s !== seriesKey));
|
||||
} else if (selectedSeries.length < MAX_SERIES) {
|
||||
setSelectedSeries([...selectedSeries, seriesKey]);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleCategory = (category) => {
|
||||
setCollapsedCategories({ ...collapsedCategories, [category]: !collapsedCategories[category] });
|
||||
};
|
||||
|
||||
const compareFields = [
|
||||
{ category: "Geral", fields: [
|
||||
{ key: "nome_completo", label: "Nome Completo" },
|
||||
{ key: "descricao", label: "Descrição" },
|
||||
]},
|
||||
{ category: "Disponibilidade e Ferramentas", fields: [
|
||||
{ key: "esp_idf_minimo", label: "ESP-IDF mínimo" },
|
||||
{ key: "arduino_core", label: "Core Arduino" },
|
||||
{ key: "depuracao", label: "Depuração / JTAG" },
|
||||
{ key: "encapsulamento", label: "Encapsulamento" },
|
||||
{ key: "modulos", label: "Módulos disponíveis" },
|
||||
]},
|
||||
{ category: "Processador", fields: [
|
||||
{ key: "arquitetura", label: "Arquitetura" },
|
||||
{ key: "nucleos", label: "Núcleos" },
|
||||
{ key: "frequencia", label: "Frequência" },
|
||||
{ key: "coprocessador_ulp", label: "Coprocessador ULP" },
|
||||
{ key: "aceleradores_ia", label: "Aceleradores de IA" },
|
||||
]},
|
||||
{ category: "Conectividade", fields: [
|
||||
{ key: "wifi", label: "Wi-Fi" },
|
||||
{ key: "bluetooth", label: "Bluetooth" },
|
||||
{ key: "zigbee_thread", label: "Zigbee/Thread" },
|
||||
{ key: "matter", label: "Matter" },
|
||||
{ key: "ethernet", label: "Ethernet" },
|
||||
]},
|
||||
{ category: "Memória", fields: [
|
||||
{ key: "memoria_sram", label: "SRAM" },
|
||||
{ key: "memoria_sram_rtc", label: "SRAM RTC" },
|
||||
{ key: "memoria_rom", label: "ROM" },
|
||||
{ key: "flash_externa", label: "Flash Externa" },
|
||||
{ key: "psram_externa", label: "PSRAM Externa" },
|
||||
]},
|
||||
{ category: "Periféricos Digitais", fields: [
|
||||
{ key: "gpio", label: "GPIO" },
|
||||
{ key: "uart", label: "UART" },
|
||||
{ key: "spi", label: "SPI" },
|
||||
{ key: "i2c", label: "I²C" },
|
||||
{ key: "i2s", label: "I²S" },
|
||||
{ key: "pwm", label: "PWM" },
|
||||
{ key: "can", label: "CAN" },
|
||||
{ key: "usb", label: "USB" },
|
||||
{ key: "depuracao", label: "Depuração / JTAG" },
|
||||
{ key: "sdio", label: "SDIO" },
|
||||
]},
|
||||
{ category: "Periféricos Analógicos", fields: [
|
||||
{ key: "adc", label: "ADC" },
|
||||
{ key: "dac", label: "DAC" },
|
||||
{ key: "touch", label: "Touch Capacitivo" },
|
||||
{ key: "sensor_hall", label: "Sensor Hall" },
|
||||
{ key: "sensor_temperatura", label: "Sensor de Temperatura" },
|
||||
]},
|
||||
{ category: "Segurança", fields: [
|
||||
{ key: "seguranca.aes", label: "AES" },
|
||||
{ key: "seguranca.sha", label: "SHA" },
|
||||
{ key: "seguranca.rsa", label: "RSA / MPI" },
|
||||
{ key: "seguranca.ecc", label: "ECC (curvas elípticas)" },
|
||||
{ key: "seguranca.ecdsa", label: "ECDSA em hardware" },
|
||||
{ key: "seguranca.hmac", label: "HMAC" },
|
||||
{ key: "seguranca.assinatura_digital", label: "Assinatura Digital (DS)" },
|
||||
{ key: "seguranca.key_manager", label: "Key Manager" },
|
||||
{ key: "seguranca.rng", label: "Gerador aleatório (RNG)" },
|
||||
{ key: "seguranca.criptografia_flash", label: "Criptografia de flash" },
|
||||
{ key: "seguranca.secure_boot", label: "Secure Boot" },
|
||||
{ key: "seguranca.protecao_dpa", label: "Proteção contra DPA" },
|
||||
]},
|
||||
{ category: "Interfaces Especiais", fields: [
|
||||
{ key: "lcd", label: "LCD" },
|
||||
{ key: "camera", label: "Câmera" },
|
||||
{ key: "mipi_csi", label: "MIPI CSI" },
|
||||
{ key: "mipi_dsi", label: "MIPI DSI" },
|
||||
{ key: "ethernet_mac", label: "Ethernet MAC" },
|
||||
]},
|
||||
{ category: "Especificações Ambientais", fields: [
|
||||
{ key: "temperatura_operacao", label: "Temp. Operação" },
|
||||
{ key: "temperatura_armazenamento", label: "Temp. Armazenamento" },
|
||||
]},
|
||||
];
|
||||
|
||||
const renderValue = (value) => {
|
||||
if (!value || value === "Não") return <span className="text-muted">Não</span>;
|
||||
if (value === "Sim") {
|
||||
return (
|
||||
<span className="inline-flex items-center gap-1.5 font-medium text-ok">
|
||||
<Check className="h-4 w-4" aria-hidden="true" />
|
||||
Sim
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return <span className="font-medium text-ink">{value}</span>;
|
||||
};
|
||||
|
||||
const valores = (key) => selectedSeries.map((k) => String(valorDe(seriesData[k], key) ?? "Não"));
|
||||
const diferem = (key) => new Set(valores(key)).size > 1;
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
<Header />
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Comparador" }]}
|
||||
icon={Scale}
|
||||
label="Até quatro séries lado a lado"
|
||||
title="Comparador de séries"
|
||||
lede="Coloque núcleos, rádio, memória, periféricos e segurança na mesma tabela e veja o que realmente muda de um chip para outro."
|
||||
/>
|
||||
|
||||
<section className="shell pt-10 sm:pt-12" aria-labelledby="escolha-titulo">
|
||||
<div className="panel p-5 sm:p-7">
|
||||
<div className="flex flex-wrap items-end justify-between gap-3">
|
||||
<div>
|
||||
<h2 id="escolha-titulo" className="text-base font-semibold text-ink">Escolha de {MIN_SERIES} a {MAX_SERIES} séries</h2>
|
||||
<p role="status" aria-live="polite" className="mt-1 text-sm text-muted">
|
||||
{selectedSeries.length} de {MAX_SERIES} selecionadas
|
||||
{selectedSeries.length === MAX_SERIES && ". Remova uma para trocar."}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 flex flex-wrap gap-2">
|
||||
{series.map(([key]) => {
|
||||
const marcada = selectedSeries.includes(key);
|
||||
const bloqueada = !marcada && selectedSeries.length >= MAX_SERIES;
|
||||
return (
|
||||
<button
|
||||
key={key}
|
||||
type="button"
|
||||
onClick={() => toggleSeries(key)}
|
||||
aria-pressed={marcada}
|
||||
aria-disabled={bloqueada}
|
||||
className={`chip-btn ${bloqueada ? "opacity-50" : ""}`}
|
||||
>
|
||||
{marcada && <Check className="h-4 w-4" aria-hidden="true" />}
|
||||
{key}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="shell mt-8" aria-labelledby="tabela-titulo">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<h2 id="tabela-titulo" className="text-base font-semibold text-ink">Especificações</h2>
|
||||
<label className="flex min-h-11 cursor-pointer items-center gap-2.5 text-sm font-medium text-ink-soft">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={soDiferencas}
|
||||
onChange={(e) => setSoDiferencas(e.target.checked)}
|
||||
className="h-5 w-5 cursor-pointer accent-[var(--accent)]"
|
||||
/>
|
||||
Mostrar só as diferenças
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="panel mt-3 overflow-hidden">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full min-w-[30rem] border-collapse text-sm">
|
||||
<caption className="sr-only">Comparação das séries {selectedSeries.join(", ")}</caption>
|
||||
<thead>
|
||||
<tr className="border-b border-line bg-surface-2">
|
||||
<th scope="col" className="sticky left-0 z-20 w-28 bg-surface-2 px-4 py-4 text-left font-semibold text-muted sm:w-52 sm:px-6">
|
||||
Especificação
|
||||
</th>
|
||||
{selectedSeries.map((seriesKey) => (
|
||||
<th key={seriesKey} scope="col" className="min-w-40 px-4 py-4 text-left sm:px-6">
|
||||
<Link href={`/series/${seriesKey}`} className="inline-flex min-h-11 items-center gap-1 font-display text-lg font-semibold tracking-[-0.03em] text-ink hover:text-accent">
|
||||
{seriesKey}
|
||||
<ArrowUpRight className="h-4 w-4 text-muted" aria-hidden="true" />
|
||||
</Link>
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{compareFields.map(({ category, fields }) => {
|
||||
const visiveis = soDiferencas ? fields.filter(({ key }) => diferem(key)) : fields;
|
||||
if (soDiferencas && visiveis.length === 0) return null;
|
||||
const isCollapsed = collapsedCategories[category] && !soDiferencas;
|
||||
return (
|
||||
<Fragment key={category}>
|
||||
<tr className="border-y border-line bg-surface-2/60">
|
||||
<th scope="rowgroup" colSpan={selectedSeries.length + 1} className="p-0 text-left">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => toggleCategory(category)}
|
||||
aria-expanded={!isCollapsed}
|
||||
className="flex min-h-12 w-full cursor-pointer items-center justify-between gap-3 px-4 py-3 text-left font-semibold text-ink sm:px-6"
|
||||
>
|
||||
<span className="sticky left-4 sm:left-6">{category}</span>
|
||||
<ChevronDown className={`h-4 w-4 shrink-0 text-muted transition-transform ${isCollapsed ? "" : "rotate-180"}`} aria-hidden="true" />
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
{!isCollapsed &&
|
||||
visiveis.map(({ key, label }) => (
|
||||
<tr key={key} className="border-b border-line last:border-b-0 hover:bg-surface-2/50">
|
||||
<th scope="row" className="sticky left-0 z-10 bg-surface px-4 py-3.5 text-left align-top font-medium text-muted sm:px-6">
|
||||
{label}
|
||||
</th>
|
||||
{selectedSeries.map((seriesKey) => (
|
||||
<td key={seriesKey} className="px-4 py-3.5 align-top sm:px-6">
|
||||
{renderValue(valorDe(seriesData[seriesKey], key))}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="shell section" aria-labelledby="docs-titulo">
|
||||
<h2 id="docs-titulo" className="section-title">Documentação oficial</h2>
|
||||
<div className="mt-6 grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{selectedSeries.map((seriesKey) => {
|
||||
const seriesItem = seriesData[seriesKey];
|
||||
return (
|
||||
<div key={seriesKey} className="card flex flex-col justify-between gap-5 p-5">
|
||||
<Link href={`/series/${seriesKey}`} className="inline-flex min-h-11 items-center font-display text-lg font-semibold tracking-[-0.03em] text-ink hover:text-accent">
|
||||
{seriesKey}
|
||||
</Link>
|
||||
{seriesItem.datasheet ? (
|
||||
<a href={seriesItem.datasheet} target="_blank" rel="noopener noreferrer" className="btn btn-ghost btn-sm">
|
||||
Datasheet oficial
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
<span className="sr-only"> (abre em nova aba)</span>
|
||||
</a>
|
||||
) : (
|
||||
<span className="text-sm text-muted">Datasheet ainda não publicado</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="panel mt-10 flex flex-col items-start justify-between gap-6 p-7 sm:p-10 md:flex-row md:items-center">
|
||||
<div className="max-w-2xl">
|
||||
<h2 className="section-title">Quer testar na bancada?</h2>
|
||||
<p className="mt-3 text-base text-muted">Veja as placas de desenvolvimento com pinagem, periféricos e link para a loja.</p>
|
||||
</div>
|
||||
<Link href="/catalogo" className="btn btn-primary shrink-0">
|
||||
Ver catálogo de placas
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export const metadata = paginaMeta({
|
||||
titulo: "ESP Component Registry & IDF Component Manager · ESPDocs",
|
||||
descricao: "Catálogo oficial e interativo do ESP Component Registry: drivers de displays, LVGL, reconhecimento de voz ESP-SR, RainMaker, BSPs e gerador de idf_component.yml.",
|
||||
caminho: "/componentes",
|
||||
keywords: [
|
||||
"ESP Component Registry",
|
||||
"IDF Component Manager",
|
||||
"idf_component.yml",
|
||||
"idf.py add-dependency",
|
||||
"componentes ESP32",
|
||||
"espressif esp_lvgl_port",
|
||||
"espressif esp_rainmaker",
|
||||
"espressif esp-sr",
|
||||
"bibliotecas ESP-IDF",
|
||||
],
|
||||
});
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
pergunta: "O que é o ESP Component Registry e o IDF Component Manager?",
|
||||
resposta: "O ESP Component Registry (components.espressif.com) é o repositório oficial de pacotes modulares da Espressif. O IDF Component Manager é a ferramenta integrada ao ESP-IDF (a partir do v4.4 e padrão no v5.x+) que baixa, compila e resolve versões de dependências automaticamente a partir do manifesto idf_component.yml.",
|
||||
},
|
||||
{
|
||||
pergunta: "Como adicionar um componente ao meu projeto ESP-IDF?",
|
||||
resposta: "Você pode executar o comando 'idf.py add-dependency \"namespace/componente^versao\"' no terminal do projeto (por exemplo: idf.py add-dependency \"espressif/esp_lvgl_port^2.4.0\") ou editar diretamente o arquivo main/idf_component.yml.",
|
||||
},
|
||||
{
|
||||
pergunta: "Qual a diferença entre usar o Component Registry e git submodules?",
|
||||
resposta: "O Component Registry elimina a complexidade de gerenciar submódulos Git pesados e versões manuais. Ele oferece versionamento semântico (^ e ~), resolução automática de dependências transitivas e compilação modular sob demanda.",
|
||||
},
|
||||
{
|
||||
pergunta: "Posso criar e publicar meus próprios componentes?",
|
||||
resposta: "Sim, qualquer desenvolvedor ou empresa pode publicar componentes públicos ou privados no ESP Component Registry utilizando a ferramenta oficial Compote CLI (pip install idf-component-manager).",
|
||||
},
|
||||
];
|
||||
|
||||
export default function ComponentesLayout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "ESP Component Registry", caminho: "/componentes" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.perguntas(faqs)),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.aplicacaoWeb({
|
||||
nome: "Hub do ESP Component Registry & Construtor de Manifesto",
|
||||
descricao: "Catálogo curado e gerador de manifesto idf_component.yml para componentes modulares do ESP-IDF.",
|
||||
caminho: "/componentes",
|
||||
})
|
||||
),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export const metadata = paginaMeta({
|
||||
titulo: "Diagnóstico de Erros Comuns no ESP32: Guia Profissional",
|
||||
descricao: "Guia técnico definitivo para identificar e resolver Brownout, Guru Meditation, Task Watchdog, Stack Overflow, vazamento de memória e falhas de boot no ESP32 (Arduino e ESP-IDF).",
|
||||
caminho: "/diagnostico",
|
||||
keywords: [
|
||||
"erros comuns ESP32",
|
||||
"brownout detector was triggered",
|
||||
"guru meditation error",
|
||||
"task watchdog got triggered",
|
||||
"stack canary watchpoint triggered",
|
||||
"como debugar ESP32",
|
||||
"ESP32 reiniciando em loop",
|
||||
"failed to connect to esp32",
|
||||
],
|
||||
});
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
pergunta: "O que causa o erro 'Brownout detector was triggered' no ESP32?",
|
||||
resposta: "Ocorre quando a tensão no pino 3V3 cai abaixo de 2.8V ~ 2.43V devido a picos rápidos de corrente do rádio Wi-Fi/BLE (superando 500mA), cabos USB finos ou regulador LDO inadequado. A solução de engenharia envolve adicionar capacitores Low-ESR de 10µF a 100µF próximos ao VCC e usar LDOs robustos de 600mA+.",
|
||||
},
|
||||
{
|
||||
pergunta: "Como resolver o 'Guru Meditation Error (LoadProhibited)'?",
|
||||
resposta: "LoadProhibited indica tentativa de acessar um ponteiro nulo (NULL) ou inválido na memória. A solução consiste em usar o Espressif Exception Decoder ou addr2line para localizar a linha exata no código e implementar validações defensivas como if (ponteiro != NULL).",
|
||||
},
|
||||
{
|
||||
pergunta: "Por que o Task Watchdog Timer (TWDT) dispara no FreeRTOS?",
|
||||
resposta: "O TWDT dispara quando uma tarefa de prioridade maior monopoliza a CPU em um loop bloqueante (ex: while(1) sem vTaskDelay), impedindo a tarefa IDLE de alimentar o watchdog do sistema operacional.",
|
||||
},
|
||||
{
|
||||
pergunta: "Por que conexões HTTPS e TLS falham com código -0x2700 no ESP32?",
|
||||
resposta: "Porque ao ligar, o ESP32 inicia o relógio interno no ano de 1970. O validador de certificados TLS considera o certificado do servidor inválido por estar no 'futuro'. Sincronizar o relógio via SNTP (configTime) antes da conexão resolve o problema.",
|
||||
},
|
||||
];
|
||||
|
||||
export default function DiagnosticoLayout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Diagnóstico & Erros Comuns", caminho: "/diagnostico" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.perguntas(faqs)
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.aplicacaoWeb({
|
||||
nome: "Guia de Diagnóstico e Erros no ESP32",
|
||||
descricao: "Ferramenta e guia técnico de análise de falhas, pânicos de CPU e decodificação de logs no ESP32.",
|
||||
caminho: "/diagnostico",
|
||||
})
|
||||
),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export const metadata = paginaMeta({
|
||||
titulo: "Frameworks & SDKs para ESP32: Guia Completo e Comparativo",
|
||||
descricao: "Guia completo de desenvolvimento: ESP-IDF, ESP-RainMaker, ESP-Matter, Rust, ESP-ADF, ESP-SR, ESP-WHO, Arduino e MicroPython com exemplos de código.",
|
||||
caminho: "/frameworks",
|
||||
keywords: [
|
||||
"ESP-IDF",
|
||||
"ESP-RainMaker",
|
||||
"ESP-Matter",
|
||||
"Rust ESP32",
|
||||
"ESP-SR",
|
||||
"ESP-ADF",
|
||||
"ESP-IoT-Solution",
|
||||
"Arduino ESP32",
|
||||
"MicroPython ESP32",
|
||||
"frameworks ESP32",
|
||||
"programar ESP32",
|
||||
],
|
||||
});
|
||||
|
||||
export default function FrameworksLayout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Frameworks", caminho: "/frameworks" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -759,4 +759,28 @@
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Tipografia e layout internacionalizados (seção 9b da spec)
|
||||
------------------------------------------------------------------------ */
|
||||
html[lang="zh-CN"] {
|
||||
font-family: "PingFang SC", "Microsoft YaHei", "Noto Sans CJK SC", "Noto Sans SC", sans-serif;
|
||||
letter-spacing: 0;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
html[lang="zh-CN"] code,
|
||||
html[lang="zh-CN"] pre,
|
||||
html[lang="zh-CN"] kbd {
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
html[lang="de"],
|
||||
html[lang="fr"] {
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
p, li, dd {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
import { categoriasGlossario } from "@/lib/glossarioData";
|
||||
|
||||
export const metadata = paginaMeta({
|
||||
titulo: "Glossário Técnico do ESP32: Termos e Conceitos",
|
||||
descricao: "Mais de 50 termos e conceitos essenciais do ecossistema ESP32 explicados em português: GPIO, Strapping Pins, ULP, PSRAM, FreeRTOS, eFuse, Deep Sleep, OTA, Secure Boot, ECDSA, Matter e Thread.",
|
||||
caminho: "/glossario",
|
||||
keywords: [
|
||||
"glossário ESP32",
|
||||
"o que é GPIO",
|
||||
"o que é strapping pins",
|
||||
"o que é ULP ESP32",
|
||||
"o que é PSRAM ESP32",
|
||||
"termos técnicos microcontrolador",
|
||||
"conceitos ESP32 português",
|
||||
],
|
||||
});
|
||||
|
||||
export default function GlossarioLayout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.glossario(categoriasGlossario)),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Glossário Técnico", caminho: "/glossario" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.aplicacaoWeb({
|
||||
nome: "Glossário Técnico do ESP32",
|
||||
descricao: "Enciclopédia de termos técnicos e conceitos de hardware e software do ecossistema ESP32.",
|
||||
caminho: "/glossario",
|
||||
})
|
||||
),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
import { JetBrains_Mono, Manrope, Space_Grotesk } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import Providers from "@/components/Providers";
|
||||
import { SITE, jsonLd } from "@/lib/seo";
|
||||
|
||||
const spaceGrotesk = Space_Grotesk({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-space-grotesk",
|
||||
display: "swap",
|
||||
weight: ["500", "600", "700"],
|
||||
});
|
||||
|
||||
const manrope = Manrope({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-manrope",
|
||||
display: "swap",
|
||||
weight: ["400", "500", "600", "700"],
|
||||
});
|
||||
|
||||
const jetbrainsMono = JetBrains_Mono({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-jetbrains",
|
||||
display: "swap",
|
||||
weight: ["400", "500", "600"],
|
||||
});
|
||||
|
||||
export const metadata = {
|
||||
// metadataBase é o que transforma caminhos relativos em URLs absolutas nas
|
||||
// tags canonical e og:image. Sem ele, o Google recebe og:image quebrado.
|
||||
metadataBase: new URL(SITE.url),
|
||||
|
||||
title: {
|
||||
default: "ESPDocs · Documentação do ESP32 em português",
|
||||
// Cada página fornece só o próprio nome; o sufixo entra automaticamente.
|
||||
template: "%s · ESPDocs",
|
||||
},
|
||||
description:
|
||||
"Especificações, pinagem, comparação e seleção das 12 séries de microcontroladores ESP32, em português brasileiro. Datasheets, periféricos, segurança em hardware e diagramas de conexão.",
|
||||
|
||||
applicationName: "ESPDocs",
|
||||
authors: [{ name: "Lucas Rayan Guerra", url: "https://lucasrguerra.dev.br" }],
|
||||
creator: "Lucas Rayan Guerra",
|
||||
publisher: "Ciência Embarcada",
|
||||
category: "technology",
|
||||
|
||||
keywords: [
|
||||
"ESP32", "ESP32 português", "documentação ESP32", "pinout ESP32",
|
||||
"ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4", "ESP32-H2",
|
||||
"comparar ESP32", "qual ESP32 escolher", "datasheet ESP32",
|
||||
"microcontrolador", "Espressif", "ESP-IDF", "IoT", "sistemas embarcados",
|
||||
],
|
||||
|
||||
alternates: { canonical: "/" },
|
||||
|
||||
openGraph: {
|
||||
type: "website",
|
||||
locale: "pt_BR",
|
||||
url: SITE.url,
|
||||
siteName: "ESPDocs",
|
||||
title: "ESPDocs · Documentação do ESP32 em português",
|
||||
description:
|
||||
"Especificações, pinagem, comparação e seleção das 12 séries de microcontroladores ESP32, em português brasileiro.",
|
||||
},
|
||||
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "ESPDocs · Documentação do ESP32 em português",
|
||||
description:
|
||||
"Especificações, pinagem, comparação e seleção das 12 séries de ESP32, em português.",
|
||||
},
|
||||
|
||||
robots: {
|
||||
index: true,
|
||||
follow: true,
|
||||
googleBot: {
|
||||
index: true,
|
||||
follow: true,
|
||||
"max-image-preview": "large",
|
||||
"max-snippet": -1,
|
||||
"max-video-preview": -1,
|
||||
},
|
||||
},
|
||||
|
||||
icons: {
|
||||
icon: [
|
||||
{ url: "/favicon.ico", sizes: "48x48", type: "image/x-icon" },
|
||||
{ url: "/favicon-48x48.png", sizes: "48x48", type: "image/png" },
|
||||
{ url: "/favicon-32x32.png", sizes: "32x32", type: "image/png" },
|
||||
{ url: "/favicon-16x16.png", sizes: "16x16", type: "image/png" },
|
||||
{ url: "/icon-192.png", sizes: "192x192", type: "image/png" },
|
||||
{ url: "/icon-512.png", sizes: "512x512", type: "image/png" },
|
||||
{ url: "/icon.svg", type: "image/svg+xml" },
|
||||
],
|
||||
apple: [
|
||||
{ url: "/apple-touch-icon.png", sizes: "180x180", type: "image/png" },
|
||||
],
|
||||
shortcut: "/favicon.ico",
|
||||
},
|
||||
manifest: "/site.webmanifest",
|
||||
formatDetection: { telephone: false, address: false, email: false },
|
||||
};
|
||||
|
||||
export const viewport = {
|
||||
themeColor: [
|
||||
{ media: "(prefers-color-scheme: light)", color: "#f5f6f8" },
|
||||
{ media: "(prefers-color-scheme: dark)", color: "#07090d" },
|
||||
],
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }) {
|
||||
return (
|
||||
<html lang="pt-BR" className={`${spaceGrotesk.variable} ${manrope.variable} ${jetbrainsMono.variable}`} suppressHydrationWarning>
|
||||
<head>
|
||||
{/* Dados estruturados do site e da organização. É o que permite ao
|
||||
Google montar o box de busca interna e entender a autoria. */}
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.siteESociedade()) }}
|
||||
/>
|
||||
</head>
|
||||
<body className="font-sans antialiased bg-canvas text-ink overflow-x-clip" suppressHydrationWarning>
|
||||
<a
|
||||
href="#conteudo"
|
||||
className="sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-4 focus:z-[200] focus:rounded-full focus:bg-ink focus:px-5 focus:py-3 focus:text-sm focus:font-semibold focus:text-canvas"
|
||||
>
|
||||
Pular para o conteúdo
|
||||
</a>
|
||||
<Providers>
|
||||
{children}
|
||||
</Providers>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import Link from "next/link";
|
||||
import { ArrowRight, BookOpen, Compass, Scale, SlidersHorizontal } from "lucide-react";
|
||||
|
||||
export const metadata = {
|
||||
title: "Página não encontrada",
|
||||
robots: { index: false, follow: false },
|
||||
};
|
||||
|
||||
const CAMINHOS = [
|
||||
{ href: "/series", icon: Compass, titulo: "Séries ESP32", texto: "As 12 famílias, com pinagem e especificações." },
|
||||
{ href: "/seletor", icon: SlidersHorizontal, titulo: "Seletor de chip", texto: "Responda a oito perguntas e receba os modelos indicados." },
|
||||
{ href: "/comparacao", icon: Scale, titulo: "Comparador", texto: "Até quatro séries lado a lado." },
|
||||
{ href: "/glossario", icon: BookOpen, titulo: "Glossário", texto: "Termos de hardware explicados em português." },
|
||||
];
|
||||
|
||||
export default function NotFound() {
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
<Header />
|
||||
|
||||
<main id="conteudo" className="shell section">
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<p className="eyebrow justify-center">Erro 404</p>
|
||||
<h1 className="page-title mt-4">Essa página não existe.</h1>
|
||||
<p className="lede mx-auto mt-5 max-w-xl">
|
||||
O endereço pode ter mudado ou estar digitado errado. Escolha um destes caminhos para continuar.
|
||||
</p>
|
||||
<div className="mt-8 flex justify-center">
|
||||
<Link href="/" className="btn btn-primary">
|
||||
Voltar ao início
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul className="mx-auto mt-14 grid max-w-4xl gap-3 sm:grid-cols-2">
|
||||
{CAMINHOS.map(({ href, icon: Icon, titulo, texto }) => (
|
||||
<li key={href}>
|
||||
<Link href={href} className="card card-interactive group flex h-full items-start gap-4 p-5">
|
||||
<span className="grid h-10 w-10 shrink-0 place-items-center rounded-full bg-accent-soft text-accent">
|
||||
<Icon className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<span>
|
||||
<span className="block font-semibold text-ink">{titulo}</span>
|
||||
<span className="mt-0.5 block text-sm text-muted">{texto}</span>
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
-341
@@ -1,341 +0,0 @@
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import BookCover from "@/components/BookCover";
|
||||
import Link from "next/link";
|
||||
import seriesData from "@/public/series.json";
|
||||
import frameworksData from "@/public/frameworks.json";
|
||||
import { SITE } from "@/lib/seo";
|
||||
import {
|
||||
AlertTriangle,
|
||||
ArrowRight,
|
||||
ArrowUpRight,
|
||||
BookOpen,
|
||||
Box,
|
||||
Cpu,
|
||||
Scale,
|
||||
SlidersHorizontal,
|
||||
Terminal,
|
||||
} from "lucide-react";
|
||||
|
||||
const FEATURED = ["ESP32", "ESP32-S3", "ESP32-C6", "ESP32-C3", "ESP32-P4", "ESP32-H2"];
|
||||
|
||||
const TOOLS = [
|
||||
{
|
||||
href: "/seletor",
|
||||
title: "Seletor inteligente",
|
||||
desc: "Responda oito perguntas sobre o projeto e receba os chips mais compatíveis, com justificativa técnica.",
|
||||
icon: SlidersHorizontal,
|
||||
action: "Encontrar meu chip",
|
||||
},
|
||||
{
|
||||
href: "/comparacao",
|
||||
title: "Comparador de séries",
|
||||
desc: "Coloque até quatro modelos lado a lado e compare núcleos, rádio, memória, periféricos e segurança.",
|
||||
icon: Scale,
|
||||
action: "Comparar agora",
|
||||
},
|
||||
{
|
||||
href: "/diagnostico",
|
||||
title: "Diagnóstico de falhas",
|
||||
desc: "Causas e correções para brownout, bootloop, Guru Meditation, watchdog e falhas de flash.",
|
||||
icon: AlertTriangle,
|
||||
action: "Abrir diagnóstico",
|
||||
},
|
||||
{
|
||||
href: "/componentes",
|
||||
title: "Component Registry",
|
||||
desc: "Drivers, bibliotecas e BSPs do registro oficial da Espressif, com manifesto pronto para o projeto.",
|
||||
icon: Box,
|
||||
action: "Explorar componentes",
|
||||
},
|
||||
{
|
||||
href: "/frameworks",
|
||||
title: "Frameworks e SDKs",
|
||||
desc: "ESP-IDF, Arduino, Rust, Matter, MicroPython e as ferramentas que ficam em volta do chip.",
|
||||
icon: Terminal,
|
||||
action: "Ver frameworks",
|
||||
},
|
||||
{
|
||||
href: "/catalogo",
|
||||
title: "Catálogo de placas",
|
||||
desc: "DevKits e módulos reais, com interface USB, sensores integrados e link para a loja oficial.",
|
||||
icon: Cpu,
|
||||
action: "Ver placas",
|
||||
},
|
||||
];
|
||||
|
||||
const ERRORS = [
|
||||
{
|
||||
code: "Brownout detector was triggered",
|
||||
cause: "Queda de tensão na inicialização do rádio.",
|
||||
fix: "Capacitor de 10–100 µF junto ao chip e fonte de 5 V com corrente suficiente.",
|
||||
},
|
||||
{
|
||||
code: "Guru Meditation Error",
|
||||
cause: "Ponteiro inválido, stack overflow ou uso incorreto de interrupção.",
|
||||
fix: "Leia o backtrace com addr2line e dimensione a stack da task no FreeRTOS.",
|
||||
},
|
||||
{
|
||||
code: "ADC2 indisponível com Wi-Fi",
|
||||
cause: "O controlador de rádio reserva o ADC2 enquanto está ativo.",
|
||||
fix: "Use os pinos do ADC1 para sensores analógicos que convivem com o Wi-Fi.",
|
||||
},
|
||||
{
|
||||
code: "Flash Read err / bootloader",
|
||||
cause: "Tensão ou modo de flash incorretos, ou pino de strapping preso no boot.",
|
||||
fix: "Confira 3,3 V, pull-ups de boot e a configuração de flash no esptool.",
|
||||
},
|
||||
];
|
||||
|
||||
export default function Home() {
|
||||
const seriesCount = Object.keys(seriesData).length;
|
||||
const frameworkCount = Object.keys(frameworksData).length;
|
||||
const featured = FEATURED.map((key) => [key, seriesData[key]]).filter(([, serie]) => Boolean(serie));
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
<Header />
|
||||
|
||||
<main id="conteudo">
|
||||
<section className="shell pb-10 pt-14 sm:pt-20 lg:pb-14 lg:pt-24">
|
||||
<div className="mx-auto max-w-4xl text-center">
|
||||
<span className="chip chip-accent">
|
||||
<Cpu className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
Documentação aberta do ESP32
|
||||
</span>
|
||||
<h1 className="display mt-6 text-[clamp(2.9rem,7.4vw,5.4rem)]">
|
||||
O ESP32,
|
||||
<br className="sm:hidden" /> sem ruído.
|
||||
</h1>
|
||||
<p className="lede mx-auto mt-6 max-w-2xl">
|
||||
Especificações, pinagem, comparações e diagnóstico em uma leitura só.
|
||||
Menos tradução de datasheet, mais tempo com o protótipo na bancada.
|
||||
</p>
|
||||
|
||||
<div className="mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row">
|
||||
<Link href="/seletor" className="btn btn-primary w-full sm:w-auto">
|
||||
<SlidersHorizontal className="h-4 w-4" aria-hidden="true" />
|
||||
Escolher meu chip
|
||||
</Link>
|
||||
<Link href="/series" className="btn btn-ghost w-full sm:w-auto">
|
||||
Explorar as {seriesCount} séries
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<p className="mt-7 flex flex-wrap items-center justify-center gap-x-5 gap-y-2 text-sm text-muted">
|
||||
<span><strong className="font-semibold text-ink">{seriesCount}</strong> séries</span>
|
||||
<span aria-hidden="true" className="text-line-strong">·</span>
|
||||
<span><strong className="font-semibold text-ink">{frameworkCount}</strong> frameworks</span>
|
||||
<span aria-hidden="true" className="text-line-strong">·</span>
|
||||
<span><strong className="font-semibold text-ink">78</strong> capítulos no livro</span>
|
||||
<span aria-hidden="true" className="text-line-strong">·</span>
|
||||
<span>100% em português</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="panel mt-12 overflow-hidden sm:mt-16">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3 px-5 py-4 sm:px-7">
|
||||
<div>
|
||||
<h2 className="text-sm font-semibold text-ink">Séries em destaque</h2>
|
||||
<p className="mt-0.5 text-xs text-muted">O essencial de cada família, antes de abrir o datasheet.</p>
|
||||
</div>
|
||||
<Link href="/series" className="inline-flex min-h-11 items-center gap-1.5 text-sm font-medium text-accent transition-colors hover:text-accent-strong">
|
||||
Índice completo
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-px border-t border-line bg-line sm:grid-cols-2 lg:grid-cols-3">
|
||||
{featured.map(([key, serie]) => (
|
||||
<Link
|
||||
key={key}
|
||||
href={`/series/${key}`}
|
||||
className="group flex min-w-0 flex-col bg-surface p-5 transition-colors duration-300 hover:bg-surface-2 sm:p-6"
|
||||
>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="min-w-0">
|
||||
<h3 className="font-display text-xl font-semibold tracking-[-0.035em] text-ink">{key}</h3>
|
||||
<p className="mt-1 truncate text-xs text-muted">{serie.arquitetura}</p>
|
||||
</div>
|
||||
<span className="grid h-9 w-9 shrink-0 place-items-center rounded-full bg-accent-soft text-accent transition-transform duration-300 group-hover:scale-105">
|
||||
<Cpu className="h-4 w-4" aria-hidden="true" />
|
||||
</span>
|
||||
</div>
|
||||
<p className="mt-5 line-clamp-2 text-sm leading-relaxed text-muted">{serie.descricao}</p>
|
||||
<div className="mt-5 flex items-center justify-between gap-3 border-t border-line pt-3.5">
|
||||
<span className="truncate font-mono text-[0.6875rem] text-ink-soft">{serie.frequencia}</span>
|
||||
<span className="inline-flex shrink-0 items-center gap-1 text-xs font-medium text-accent">
|
||||
Ficha
|
||||
<ArrowUpRight className="h-3.5 w-3.5 transition-transform duration-300 group-hover:-translate-y-0.5 group-hover:translate-x-0.5" aria-hidden="true" />
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="shell section pt-8 sm:pt-12" aria-labelledby="livro-titulo">
|
||||
<div className="relative isolate overflow-hidden rounded-[2rem] bg-[#0b0d10] ring-1 ring-white/10 dark:bg-[#05070a] dark:ring-white/15 sm:rounded-[2.5rem]">
|
||||
<div
|
||||
className="pointer-events-none absolute -left-24 top-1/2 -z-10 h-80 w-80 -translate-y-1/2 rounded-full bg-[#2dd4bf]/15 blur-3xl"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div className="grid lg:grid-cols-[0.82fr_1.18fr]">
|
||||
<div className="order-1 flex flex-col justify-center p-7 sm:p-10 lg:order-2 lg:p-14">
|
||||
<span className="inline-flex w-fit items-center gap-2 rounded-full border border-white/15 bg-white/5 px-3 py-1 text-xs font-semibold text-[#75cdc1]">
|
||||
<BookOpen className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
Livro novo
|
||||
</span>
|
||||
<h2 id="livro-titulo" className="mt-5 font-display text-[clamp(2rem,4.2vw,3.2rem)] font-semibold leading-[1.05] tracking-[-0.04em] text-[#f4f6f8]">
|
||||
{SITE.livroTitulo}
|
||||
</h2>
|
||||
<p className="mt-2 text-base text-[#a6afbd]">{SITE.livroSubtitulo}</p>
|
||||
<p className="mt-5 max-w-xl text-sm leading-relaxed text-[#c4cbd5]">
|
||||
Um percurso completo pelo hardware e pelo firmware do ESP32: da arquitetura do chip
|
||||
à implantação de produtos conectados. São 12 partes e 78 capítulos sobre Arduino,
|
||||
ESP-IDF, FreeRTOS, Wi-Fi, BLE, Thread e Matter, periféricos, depuração, baixo consumo
|
||||
e segurança.
|
||||
</p>
|
||||
|
||||
<p className="mt-6 flex flex-wrap items-center gap-x-3 gap-y-1.5 text-xs text-[#a6afbd]">
|
||||
<span>12 partes</span>
|
||||
<span aria-hidden="true" className="text-white/20">·</span>
|
||||
<span>78 capítulos</span>
|
||||
<span aria-hidden="true" className="text-white/20">·</span>
|
||||
<span>ISBN {SITE.livroIsbn}</span>
|
||||
</p>
|
||||
|
||||
<div className="mt-7 flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center">
|
||||
<a
|
||||
href={SITE.livroAmazon}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex min-h-11 items-center justify-center gap-2 rounded-full bg-[#2dd4bf] px-5 text-sm font-semibold text-[#06201d] transition-colors duration-300 hover:bg-[#5eead4]"
|
||||
>
|
||||
Comprar digital
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
<a
|
||||
href={SITE.livroUiclap}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex min-h-11 items-center justify-center gap-2 rounded-full border border-white/20 px-5 text-sm font-semibold text-[#f4f6f8] transition-colors duration-300 hover:border-white/40 hover:bg-white/5"
|
||||
>
|
||||
Comprar impresso
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
<Link href="/livro" className="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-full px-3 text-sm font-medium text-[#a6afbd] transition-colors duration-300 hover:text-[#f4f6f8]">
|
||||
Ficha completa
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="order-2 flex items-center justify-center border-t border-white/10 p-8 sm:p-12 lg:order-1 lg:border-r lg:border-t-0 lg:p-14">
|
||||
<div className="relative w-[min(15.5rem,68%)] lg:w-[min(17rem,100%)]">
|
||||
<div className="absolute -inset-10 -z-10 rounded-full bg-[#2dd4bf]/10 blur-3xl" aria-hidden="true" />
|
||||
<BookCover />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="shell section" aria-labelledby="ferramentas-titulo">
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<p className="eyebrow">Ferramentas</p>
|
||||
<h2 id="ferramentas-titulo" className="display mt-4 text-[clamp(2rem,4.8vw,3.4rem)]">
|
||||
Comece pelo problema.
|
||||
</h2>
|
||||
<p className="lede mt-4">
|
||||
Cada ferramenta resolve uma etapa concreta do projeto, sem cadastro e sem rodeio.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{TOOLS.map((tool) => {
|
||||
const Icon = tool.icon;
|
||||
return (
|
||||
<Link key={tool.href} href={tool.href} className="card card-interactive group flex flex-col p-5 sm:p-6">
|
||||
<span className="grid h-11 w-11 place-items-center rounded-2xl bg-accent-soft text-accent">
|
||||
<Icon className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<h3 className="mt-5 font-display text-lg font-semibold tracking-[-0.025em] text-ink">{tool.title}</h3>
|
||||
<p className="mt-2 flex-1 text-sm leading-relaxed text-muted">{tool.desc}</p>
|
||||
<span className="mt-5 inline-flex items-center gap-1.5 text-sm font-medium text-accent">
|
||||
{tool.action}
|
||||
<ArrowRight className="h-4 w-4 transition-transform duration-300 group-hover:translate-x-0.5" aria-hidden="true" />
|
||||
</span>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="shell section pt-0" aria-labelledby="diagnostico-titulo">
|
||||
<div className="grid items-start gap-10 lg:grid-cols-[0.78fr_1.22fr] lg:gap-16">
|
||||
<div className="lg:sticky lg:top-28">
|
||||
<p className="eyebrow">Diagnóstico</p>
|
||||
<h2 id="diagnostico-titulo" className="display mt-4 text-[clamp(2rem,4.8vw,3.4rem)]">
|
||||
O primeiro boot não precisa virar noite.
|
||||
</h2>
|
||||
<p className="lede mt-4">
|
||||
Os erros mais comuns têm causa conhecida. O guia parte da mensagem no terminal e chega ao ajuste de hardware ou firmware.
|
||||
</p>
|
||||
<Link href="/diagnostico" className="btn btn-accent mt-7">
|
||||
<AlertTriangle className="h-4 w-4" aria-hidden="true" />
|
||||
Abrir os 30+ diagnósticos
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="panel-dark min-w-0 overflow-hidden rounded-[1.75rem]">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3 border-b border-white/10 px-5 py-4 sm:px-6">
|
||||
<span className="inline-flex items-center gap-2 font-mono text-xs text-[#75cdc1]">
|
||||
<Terminal className="h-4 w-4" aria-hidden="true" />
|
||||
boot.log
|
||||
</span>
|
||||
<span className="text-xs text-[#a6afbd]">4 exemplos de 30+</span>
|
||||
</div>
|
||||
<div className="divide-y divide-white/10">
|
||||
{ERRORS.map((item) => (
|
||||
<Link key={item.code} href="/diagnostico" className="group grid gap-2 px-5 py-5 transition-colors duration-300 hover:bg-white/[0.035] sm:px-6">
|
||||
<span className="break-words font-mono text-[0.75rem] font-medium leading-relaxed text-[#ffb39b]">{item.code}</span>
|
||||
<span className="text-sm font-medium text-[#f4f6f8]">{item.cause}</span>
|
||||
<span className="text-xs leading-relaxed text-[#a6afbd]">{item.fix}</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="shell pb-20 pt-4 md:pb-28">
|
||||
<div className="mx-auto max-w-3xl text-center">
|
||||
<p className="eyebrow">Curadoria independente</p>
|
||||
<h2 className="display mt-4 text-[clamp(2rem,4.5vw,3.2rem)]">
|
||||
Feito para consultar no meio do projeto.
|
||||
</h2>
|
||||
<p className="lede mx-auto mt-4 max-w-2xl">
|
||||
O ESPDocs organiza dados públicos da Espressif e aponta sempre para a fonte oficial.
|
||||
Para decisões críticas, o datasheet e o Technical Reference Manual continuam sendo a palavra final.
|
||||
</p>
|
||||
<div className="mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row">
|
||||
<Link href="/glossario" className="btn btn-ghost w-full sm:w-auto">
|
||||
<BookOpen className="h-4 w-4" aria-hidden="true" />
|
||||
Glossário
|
||||
</Link>
|
||||
<Link href="/sobre" className="btn btn-primary w-full sm:w-auto">
|
||||
Sobre o projeto
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export const metadata = paginaMeta({
|
||||
titulo: "Qual ESP32 escolher",
|
||||
descricao: "Responda a perguntas simples sobre conectividade (Wi-Fi 6, 5GHz, Matter), energia, periféricos e segurança ou use o filtro paramétrico para encontrar o ESP32 perfeito.",
|
||||
caminho: "/seletor",
|
||||
keywords: ["qual ESP32 escolher", "qual ESP32 usar", "escolher microcontrolador", "ESP32 para meu projeto", "comparar ESP32"],
|
||||
});
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
pergunta: "Qual ESP32 escolher para iniciantes?",
|
||||
resposta: "Para quem está começando no mundo Maker e IoT, o ESP32 clássico (NodeMCU/DevKitC) ou o ESP32-C3 são as melhores opções devido à vasta quantidade de bibliotecas, exemplos prontos no Arduino IDE e farta documentação em português.",
|
||||
},
|
||||
{
|
||||
pergunta: "Qual ESP32 tem suporte a Wi-Fi 6, Bluetooth 6 e Thread/Zigbee/Matter?",
|
||||
resposta: "O ESP32-C6 e o ESP32-C5 são as melhores séries para redes modernas. O ESP32-C6 oferece Wi-Fi 6 (2.4 GHz) e rádio 802.15.4 (Zigbee 3.0 / Thread / Matter). Já o ESP32-C5 é o primeiro a oferecer suporte a Wi-Fi 6 Dual-Band operando em 2.4 GHz e 5 GHz simultaneamente.",
|
||||
},
|
||||
{
|
||||
pergunta: "Qual o ESP32 mais potente para Inteligência Artificial (TinyML) e Displays?",
|
||||
resposta: "O ESP32-P4 (dual-core RISC-V a 400 MHz com extensões vetoriais de IA, interfaces MIPI-CSI/DSI para câmeras/telas e até 64 MB de PSRAM) e o ESP32-S3 (dual-core Xtensa a 240 MHz com aceleradores vetoriais para redes neurais e telas LCD RGB) são os mais velozes para IA na borda e interfaces gráficas ricas.",
|
||||
},
|
||||
{
|
||||
pergunta: "Qual ESP32 consome menos energia para projetos a bateria?",
|
||||
resposta: "Microcontroladores com arquitetura RISC-V compacta e coprocessador ULP, como o ESP32-C2, ESP32-C3 e ESP32-H2 (focado em 802.15.4 sem rádio Wi-Fi), oferecem correntes de deep sleep extremamente baixas (na faixa de 5 µA a 10 µA).",
|
||||
},
|
||||
];
|
||||
|
||||
export default function Layout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.aplicacaoWeb({
|
||||
nome: "Seletor Inteligente de ESP32",
|
||||
descricao: "Ferramenta interativa que analisa conectividade, consumo, periféricos e segurança para indicar a série ideal de ESP32.",
|
||||
caminho: "/seletor",
|
||||
})
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Seletor de ESP32", caminho: "/seletor" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.perguntas(faqs)),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,488 +0,0 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import { notFound } from "next/navigation";
|
||||
import seriesData from "@/public/series.json";
|
||||
import ConnectionsDiagram from "@/components/ConnectionsDiagram";
|
||||
import SeriesTabMenu from "@/components/SeriesTabMenu";
|
||||
import PinRestrictions from "@/components/PinRestrictions";
|
||||
import {
|
||||
AlertTriangle,
|
||||
ArrowLeft,
|
||||
ArrowRight,
|
||||
ArrowUpRight,
|
||||
Battery,
|
||||
BookOpen,
|
||||
Code,
|
||||
Cpu,
|
||||
Database,
|
||||
ExternalLink,
|
||||
FileText,
|
||||
Lightbulb,
|
||||
Package,
|
||||
Scale,
|
||||
ShieldCheck,
|
||||
Sliders,
|
||||
Thermometer,
|
||||
Wifi,
|
||||
} from "lucide-react";
|
||||
|
||||
export default async function SerieDetail({ params }) {
|
||||
const { key } = await params;
|
||||
const serie = seriesData[key];
|
||||
|
||||
if (!serie) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
let conexoes = [];
|
||||
try {
|
||||
conexoes = require(`@/public/conexoes/${key}.json`);
|
||||
} catch (error) {
|
||||
console.log(`Arquivo de conexões não encontrado para ${key}`);
|
||||
}
|
||||
|
||||
const seriesKeys = Object.keys(seriesData);
|
||||
const currentIndex = seriesKeys.indexOf(key);
|
||||
const previousKey = currentIndex > 0 ? seriesKeys[currentIndex - 1] : null;
|
||||
const nextKey = currentIndex < seriesKeys.length - 1 ? seriesKeys[currentIndex + 1] : null;
|
||||
|
||||
const processadorSpecs = [
|
||||
{ label: "Arquitetura", value: serie.arquitetura },
|
||||
{ label: "Núcleos", value: serie.nucleos },
|
||||
{ label: "Frequência", value: serie.frequencia },
|
||||
{ label: "Coprocessador ULP", value: serie.coprocessador_ulp || "Não" },
|
||||
{ label: "Aceleradores IA", value: serie.aceleradores_ia || "Não" },
|
||||
];
|
||||
|
||||
const seg = serie.seguranca || {};
|
||||
const segurancaSpecs = [
|
||||
{ label: "AES", value: seg.aes || "Não" },
|
||||
{ label: "SHA", value: seg.sha || "Não" },
|
||||
{ label: "RSA / MPI", value: seg.rsa || "Não" },
|
||||
{ label: "ECC (curvas elípticas)", value: seg.ecc || "Não" },
|
||||
{ label: "ECDSA em hardware", value: seg.ecdsa || "Não" },
|
||||
{ label: "HMAC", value: seg.hmac || "Não" },
|
||||
{ label: "Assinatura Digital (DS)", value: seg.assinatura_digital || "Não" },
|
||||
{ label: "Key Manager", value: seg.key_manager || "Não" },
|
||||
{ label: "Gerador aleatório (RNG)", value: seg.rng || "Não" },
|
||||
{ label: "Criptografia de flash", value: seg.criptografia_flash || "Não" },
|
||||
{ label: "Secure Boot", value: seg.secure_boot || "Não" },
|
||||
{ label: "Proteção contra DPA", value: seg.protecao_dpa || "Não" },
|
||||
];
|
||||
|
||||
const ferramentasSpecs = [
|
||||
{ label: "ESP-IDF mínimo", value: serie.esp_idf_minimo || "Não informado" },
|
||||
{ label: "Core Arduino", value: serie.arduino_core || "Não informado" },
|
||||
{ label: "Depuração", value: serie.depuracao || "Não informado" },
|
||||
{ label: "Encapsulamento", value: serie.encapsulamento || "Não informado" },
|
||||
{ label: "Módulos disponíveis", value: serie.modulos || "Não informado" },
|
||||
];
|
||||
|
||||
const conectividadeSpecs = [
|
||||
{ label: "Wi-Fi", value: serie.wifi || "Não" },
|
||||
{ label: "Bluetooth", value: serie.bluetooth || "Não" },
|
||||
{ label: "Zigbee/Thread", value: serie.zigbee_thread || "Não" },
|
||||
{ label: "Matter", value: serie.matter || "Não" },
|
||||
{ label: "Ethernet", value: serie.ethernet || serie.ethernet_mac || "Não" },
|
||||
{ label: "CAN", value: serie.can || "Não" },
|
||||
];
|
||||
|
||||
const memoriaSpecs = [
|
||||
{ label: "SRAM", value: serie.memoria_sram },
|
||||
{ label: "SRAM RTC", value: serie.memoria_sram_rtc },
|
||||
{ label: "ROM", value: serie.memoria_rom },
|
||||
{ label: "Flash Externa", value: serie.flash_externa },
|
||||
{ label: "PSRAM Externa", value: serie.psram_externa || "Não" },
|
||||
];
|
||||
|
||||
const perifericos = [
|
||||
{ label: "GPIO", value: serie.gpio },
|
||||
{ label: "ADC", value: serie.adc },
|
||||
{ label: "DAC", value: serie.dac || "Não" },
|
||||
{ label: "Touch", value: serie.touch || "Não" },
|
||||
{ label: "UART", value: serie.uart },
|
||||
{ label: "SPI", value: serie.spi },
|
||||
{ label: "I2C", value: serie.i2c },
|
||||
{ label: "I2S", value: serie.i2s },
|
||||
{ label: "PWM", value: serie.pwm },
|
||||
{ label: "USB", value: serie.usb || "Não" },
|
||||
];
|
||||
|
||||
const interfacesEspeciais = [];
|
||||
if (serie.lcd) interfacesEspeciais.push({ label: "LCD", value: serie.lcd });
|
||||
if (serie.camera) interfacesEspeciais.push({ label: "Câmera", value: serie.camera });
|
||||
if (serie.mipi_csi) interfacesEspeciais.push({ label: "MIPI CSI", value: serie.mipi_csi });
|
||||
if (serie.mipi_dsi) interfacesEspeciais.push({ label: "MIPI DSI", value: serie.mipi_dsi });
|
||||
if (serie.sdio) interfacesEspeciais.push({ label: "SDIO", value: serie.sdio });
|
||||
if (serie.sensor_hall) interfacesEspeciais.push({ label: "Sensor Hall", value: serie.sensor_hall });
|
||||
if (serie.sensor_temperatura) interfacesEspeciais.push({ label: "Sensor Temperatura", value: serie.sensor_temperatura });
|
||||
|
||||
// Consumo de Energia
|
||||
const consumoEnergia = [];
|
||||
if (serie.consumo_energia) {
|
||||
Object.entries(serie.consumo_energia).forEach(([modo, consumo]) => {
|
||||
const modoLabels = {
|
||||
'active': 'Modo Ativo',
|
||||
'active_cpu_240mhz': 'Ativo (CPU 240MHz)',
|
||||
'active_cpu_160mhz': 'Ativo (CPU 160MHz)',
|
||||
'active_wifi_tx': 'Ativo (Wi-Fi TX)',
|
||||
'active_wifi_tx_peak': 'Ativo (Wi-Fi TX Pico)',
|
||||
'active_wifi': 'Ativo (Wi-Fi)',
|
||||
'active_wifi6': 'Ativo (Wi-Fi 6)',
|
||||
'modem_sleep': 'Modem Sleep',
|
||||
'modem_sleep_cpu_160mhz': 'Modem Sleep (CPU 160MHz)',
|
||||
'light_sleep': 'Light Sleep',
|
||||
'deep_sleep': 'Deep Sleep',
|
||||
'hibernation': 'Hibernação'
|
||||
};
|
||||
|
||||
consumoEnergia.push({
|
||||
label: modoLabels[modo] || modo.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()),
|
||||
value: consumo
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
id: "devboard",
|
||||
label: "Placa de desenvolvimento",
|
||||
available: serie.placa,
|
||||
content: (
|
||||
<div className="card p-5 sm:p-7">
|
||||
<h2 className="text-lg font-semibold text-ink">Kit de desenvolvimento oficial</h2>
|
||||
<div className="mt-5 overflow-hidden rounded-xl border border-line bg-surface-2 p-4">
|
||||
<Image
|
||||
src={serie.placa}
|
||||
alt={`Placa de desenvolvimento ${key}`}
|
||||
width={1200}
|
||||
height={800}
|
||||
className="mx-auto h-auto max-h-[28rem] w-full rounded-lg object-contain"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
<p className="mt-3 text-sm text-muted">Placa padrão da Espressif para a série {key}.</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "connections",
|
||||
label: "Diagrama de conexões",
|
||||
available: conexoes.length > 0,
|
||||
content: (
|
||||
<div className="card p-5 sm:p-7">
|
||||
<div className="callout callout-warn flex items-start gap-3">
|
||||
<AlertTriangle className="mt-0.5 h-5 w-5 shrink-0 text-gold" aria-hidden="true" />
|
||||
<div>
|
||||
<p className="font-semibold text-ink">Este é o diagrama do chip, não da placa</p>
|
||||
<p className="mt-1">
|
||||
O mapa mostra as conexões do silício do <strong>{key}</strong>. Cada placa de desenvolvimento
|
||||
expõe só parte delas, ou as roteia de outra forma.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6">
|
||||
<ConnectionsDiagram connections={conexoes} serie={serie} />
|
||||
</div>
|
||||
|
||||
<div className="callout mt-8">
|
||||
<p className="flex items-center gap-2 font-semibold text-ink">
|
||||
<Lightbulb className="h-4 w-4 text-accent" aria-hidden="true" />
|
||||
Quase todo pino é reconfigurável
|
||||
</p>
|
||||
<p className="mt-1">
|
||||
A matriz de IO do {key} permite mover SPI, I2C, UART, PWM e barramentos de câmera ou display
|
||||
para a maioria dos pinos digitais. Para as restrições de strapping e dos pinos analógicos,
|
||||
consulte o{" "}
|
||||
<a
|
||||
href={`https://docs.espressif.com/projects/esp-idf/en/latest/${String(key).toLowerCase().replace("-", "")}/api-reference/peripherals/gpio.html`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-1 font-medium text-accent underline decoration-accent/30 underline-offset-2 hover:decoration-accent"
|
||||
>
|
||||
guia oficial de GPIO
|
||||
<ExternalLink className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const secoes = [
|
||||
{ id: "processador", titulo: "Processador", icon: Cpu, specs: processadorSpecs },
|
||||
{ id: "conectividade", titulo: "Conectividade", icon: Wifi, specs: conectividadeSpecs },
|
||||
{ id: "ferramentas", titulo: "Ferramentas e disponibilidade", icon: Package, specs: ferramentasSpecs },
|
||||
{ id: "seguranca", titulo: "Segurança", icon: ShieldCheck, specs: segurancaSpecs },
|
||||
{ id: "memoria", titulo: "Memória", icon: Database, specs: memoriaSpecs },
|
||||
...(consumoEnergia.length > 0
|
||||
? [{
|
||||
id: "energia",
|
||||
titulo: "Consumo de energia",
|
||||
icon: Battery,
|
||||
specs: consumoEnergia,
|
||||
nota: "Valores típicos a 3,3 V e 25 °C. O consumo real depende do ciclo de trabalho do rádio e da frequência de clock configurada.",
|
||||
}]
|
||||
: []),
|
||||
{ id: "perifericos", titulo: "Periféricos", icon: Sliders, specs: perifericos },
|
||||
...(interfacesEspeciais.length > 0
|
||||
? [{ id: "interfaces", titulo: "Interfaces especiais", icon: Sliders, specs: interfacesEspeciais }]
|
||||
: []),
|
||||
{
|
||||
id: "temperatura",
|
||||
titulo: "Limites de temperatura",
|
||||
icon: Thermometer,
|
||||
specs: [
|
||||
{ label: "Operação", value: serie.temperatura_operacao },
|
||||
{ label: "Armazenamento", value: serie.temperatura_armazenamento },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const fatos = [
|
||||
{ label: "Processador", value: String(serie.nucleos).includes("2") ? "Dual-core" : "Single-core", detail: serie.frequencia },
|
||||
{ label: "SRAM", value: serie.memoria_sram, detail: `+ ${serie.memoria_sram_rtc} de SRAM RTC` },
|
||||
{ label: "GPIO", value: serie.gpio, detail: "pinos programáveis" },
|
||||
{ label: "Arquitetura", value: String(serie.arquitetura).includes("RISC-V") ? "RISC-V" : "Xtensa", detail: serie.arquitetura },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.serie(key, serie)) }}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Séries", caminho: "/series" },
|
||||
{ nome: serie.nome_completo, caminho: `/series/${key}` },
|
||||
])),
|
||||
}}
|
||||
/>
|
||||
|
||||
<Header />
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Séries", href: "/series" }, { label: key }]}
|
||||
icon={Cpu}
|
||||
label={serie.arquitetura}
|
||||
title={key}
|
||||
lede={serie.descricao}
|
||||
>
|
||||
{serie.datasheet ? (
|
||||
<a href={serie.datasheet} target="_blank" rel="noopener noreferrer" className="btn btn-primary">
|
||||
<FileText className="h-4 w-4" aria-hidden="true" />
|
||||
Datasheet oficial
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
) : (
|
||||
<span className="btn btn-ghost cursor-not-allowed opacity-70" aria-disabled="true">
|
||||
<FileText className="h-4 w-4" aria-hidden="true" />
|
||||
Datasheet ainda não publicado
|
||||
</span>
|
||||
)}
|
||||
{serie.guia_de_programacao && (
|
||||
<a href={serie.guia_de_programacao} target="_blank" rel="noopener noreferrer" className="btn btn-ghost">
|
||||
<Code className="h-4 w-4" aria-hidden="true" />
|
||||
Guia de programação
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
)}
|
||||
{serie.manual_tecnico && (
|
||||
<a href={serie.manual_tecnico} target="_blank" rel="noopener noreferrer" className="btn btn-ghost">
|
||||
<BookOpen className="h-4 w-4" aria-hidden="true" />
|
||||
Manual técnico
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
)}
|
||||
</PageHero>
|
||||
|
||||
<section className="shell mt-10" aria-label="Resumo">
|
||||
<dl className="grid grid-cols-2 gap-3 lg:grid-cols-4">
|
||||
{fatos.map((fato) => (
|
||||
<div key={fato.label} className="tile">
|
||||
<dt className="text-xs font-medium text-muted">{fato.label}</dt>
|
||||
<dd className="mt-1 font-display text-2xl font-semibold tracking-[-0.03em] text-ink">{fato.value}</dd>
|
||||
<dd className="mt-0.5 text-xs text-muted">{fato.detail}</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
|
||||
{serie.status_documentacao && (
|
||||
<div className="callout callout-warn mt-4 flex items-start gap-3">
|
||||
<AlertTriangle className="mt-0.5 h-5 w-5 shrink-0 text-gold" aria-hidden="true" />
|
||||
<div>
|
||||
<p className="font-semibold text-ink">Documentação preliminar</p>
|
||||
<p className="mt-1">{serie.status_documentacao}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
|
||||
<div className="shell mt-10">
|
||||
<SeriesTabMenu tabs={tabs} />
|
||||
<PinRestrictions conexoes={conexoes} serieKey={key} />
|
||||
</div>
|
||||
|
||||
<div className="shell mt-12">
|
||||
<nav
|
||||
aria-label="Seções da ficha"
|
||||
className="nav-pill no-scrollbar sticky top-20 z-30 flex gap-1 overflow-x-auto rounded-full p-1.5"
|
||||
>
|
||||
{secoes.map((secao) => (
|
||||
<a key={secao.id} href={`#${secao.id}`} className="nav-link shrink-0">
|
||||
{secao.titulo}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<div className="mt-8 space-y-5">
|
||||
{secoes.map((secao) => (
|
||||
<SpecSection key={secao.id} {...secao} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section className="shell section">
|
||||
<div className="panel flex flex-col items-start justify-between gap-6 p-7 sm:p-10 md:flex-row md:items-center">
|
||||
<div className="max-w-2xl">
|
||||
<h2 className="section-title">Pronto para prototipar o {key}?</h2>
|
||||
<p className="mt-3 text-base text-muted">
|
||||
Veja as placas de desenvolvimento disponíveis para a série, com USB, sensores integrados e link para a loja oficial.
|
||||
</p>
|
||||
</div>
|
||||
<Link href="/catalogo" className="btn btn-primary shrink-0">
|
||||
Ver placas
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<nav aria-label="Outras séries" className="mt-6 grid gap-3 sm:grid-cols-[1fr_auto_1fr] sm:items-center">
|
||||
{previousKey ? (
|
||||
<Link href={`/series/${previousKey}`} className="card card-interactive group flex items-center gap-3 px-5 py-4">
|
||||
<ArrowLeft className="h-4 w-4 text-muted transition-transform group-hover:-translate-x-1" aria-hidden="true" />
|
||||
<span>
|
||||
<span className="block text-xs text-muted">Série anterior</span>
|
||||
<span className="block font-display text-lg font-semibold text-ink">{previousKey}</span>
|
||||
</span>
|
||||
</Link>
|
||||
) : (
|
||||
<span className="hidden sm:block" />
|
||||
)}
|
||||
<Link href="/comparacao" className="btn btn-ghost justify-self-center">
|
||||
<Scale className="h-4 w-4" aria-hidden="true" />
|
||||
Comparar séries
|
||||
</Link>
|
||||
{nextKey ? (
|
||||
<Link href={`/series/${nextKey}`} className="card card-interactive group flex items-center justify-end gap-3 px-5 py-4 text-right">
|
||||
<span>
|
||||
<span className="block text-xs text-muted">Próxima série</span>
|
||||
<span className="block font-display text-lg font-semibold text-ink">{nextKey}</span>
|
||||
</span>
|
||||
<ArrowRight className="h-4 w-4 text-muted transition-transform group-hover:translate-x-1" aria-hidden="true" />
|
||||
</Link>
|
||||
) : (
|
||||
<span className="hidden sm:block" />
|
||||
)}
|
||||
</nav>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SpecSection({ id, titulo, icon: Icon, specs, nota }) {
|
||||
return (
|
||||
<section id={id} aria-labelledby={`${id}-titulo`} className="card scroll-mt-36 p-5 sm:p-7">
|
||||
<h2 id={`${id}-titulo`} className="flex items-center gap-3 font-display text-xl font-semibold tracking-[-0.03em] text-ink">
|
||||
<span className="grid h-9 w-9 place-items-center rounded-full bg-accent-soft text-accent">
|
||||
<Icon className="h-4 w-4" aria-hidden="true" />
|
||||
</span>
|
||||
{titulo}
|
||||
</h2>
|
||||
{nota && <p className="mt-3 text-sm text-muted">{nota}</p>}
|
||||
<dl className="mt-5 grid grid-cols-2 gap-3 lg:grid-cols-3">
|
||||
{specs.map((spec) => {
|
||||
const negativo = /^n[ãa]o\b/i.test(String(spec.value));
|
||||
return (
|
||||
<div key={spec.label} className="tile">
|
||||
<dt className="text-xs font-medium text-muted">{spec.label}</dt>
|
||||
<dd className={`mt-1 text-sm font-semibold leading-snug ${negativo ? "text-muted" : "text-ink"}`}>{spec.value}</dd>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</dl>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { key } = await params;
|
||||
const serie = seriesData[key];
|
||||
|
||||
if (!serie) {
|
||||
return { title: "Série não encontrada", robots: { index: false, follow: false } };
|
||||
}
|
||||
|
||||
// A descrição usa as especificações reais em vez de texto genérico: é o que
|
||||
// aparece no resultado de busca e o que faz alguém clicar.
|
||||
const radio = [
|
||||
String(serie.wifi).startsWith("Não") ? null : serie.wifi.split(" (")[0],
|
||||
String(serie.bluetooth).startsWith("Não") ? null : serie.bluetooth.split(" (")[0],
|
||||
serie.zigbee_thread && !String(serie.zigbee_thread).startsWith("Não") ? "802.15.4" : null,
|
||||
].filter(Boolean).join(", ");
|
||||
|
||||
const descricao =
|
||||
`${serie.nome_completo}: ${serie.arquitetura}, ${serie.frequencia.replace("Até ", "até ")}, ` +
|
||||
`${serie.memoria_sram} de SRAM e ${serie.gpio} GPIOs` +
|
||||
(radio ? `. Rádio: ${radio}` : "") +
|
||||
`. Pinagem completa, periféricos, segurança em hardware e pinos com restrição, em português.`;
|
||||
|
||||
// A pinagem da placa é a melhor prévia possível para uma série: quem
|
||||
// compartilha o link já mostra o diagrama. Séries sem placa publicada caem
|
||||
// na imagem padrão do site.
|
||||
// Definir openGraph explicitamente impede a herança automática da imagem do
|
||||
// site, então séries sem placa publicada (o H4) precisam do fallback aqui.
|
||||
const imagem = serie.placa
|
||||
? [{ url: serie.placa, width: 1600, height: 1091, alt: `Pinagem do ${serie.nome_completo}` }]
|
||||
: [{ url: "/opengraph-image.png", width: 1200, height: 630, alt: "ESPDocs" }];
|
||||
|
||||
const meta = {
|
||||
...paginaMeta({
|
||||
titulo: `${serie.nome_completo}: especificações e pinagem`,
|
||||
descricao,
|
||||
caminho: `/series/${key}`,
|
||||
tipo: "article",
|
||||
keywords: [
|
||||
serie.nome_completo, `${serie.nome_completo} pinout`,
|
||||
`${serie.nome_completo} datasheet`, `${serie.nome_completo} especificações`,
|
||||
`${serie.nome_completo} português`, "ESP32", "Espressif", "microcontrolador",
|
||||
],
|
||||
}),
|
||||
other: { "article:section": "Séries ESP32" },
|
||||
};
|
||||
|
||||
meta.openGraph = { ...meta.openGraph, images: imagem };
|
||||
meta.twitter = { ...meta.twitter, images: imagem };
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return Object.keys(seriesData).map((key) => ({
|
||||
key: key,
|
||||
}));
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
|
||||
export const metadata = paginaMeta({
|
||||
titulo: "Séries ESP32",
|
||||
descricao: "As 12 séries de ESP32 lado a lado: ESP32, S2, S3, S31, C2, C3, C5, C6, C61, P4, H2 e H4. Arquitetura, memória, rádio, periféricos e pinagem de cada uma, em português.",
|
||||
caminho: "/series",
|
||||
keywords: ["séries ESP32", "modelos de ESP32", "ESP32 S3", "ESP32 C6", "ESP32 P4", "diferença entre ESP32"],
|
||||
});
|
||||
|
||||
metadata.title = { default: "Séries ESP32", template: "%s · ESPDocs" };
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
pergunta: "Quantas séries de ESP32 existem atualmente?",
|
||||
resposta: "Atualmente o ecossistema Espressif conta com 12 séries principais: ESP32 clássico, ESP32-S2, ESP32-S3, ESP32-S31, ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-P4, ESP32-H2 e ESP32-H4.",
|
||||
},
|
||||
{
|
||||
pergunta: "Quais são as séries mais recentes da Espressif?",
|
||||
resposta: "As séries mais recentes incluem o ESP32-P4 (focado em alto desempenho com dual-core RISC-V a 400 MHz), o ESP32-C5 (primeiro chip com Wi-Fi dual-band 2.4/5 GHz da Espressif) e o ESP32-C61 (Wi-Fi 6 e Bluetooth 6 de baixo custo).",
|
||||
},
|
||||
];
|
||||
|
||||
export default function Layout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Séries ESP32", caminho: "/series" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.perguntas(faqs)),
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { useMemo, useState } from "react";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import Link from "next/link";
|
||||
import seriesData from "@/public/series.json";
|
||||
import {
|
||||
AlertTriangle,
|
||||
ArrowRight,
|
||||
ArrowUpRight,
|
||||
Compass,
|
||||
Home,
|
||||
Scale,
|
||||
ShieldCheck,
|
||||
Sparkles,
|
||||
} from "lucide-react";
|
||||
|
||||
const FILTROS = [
|
||||
{ id: "todas", rotulo: "Todas", testa: () => true },
|
||||
{ id: "riscv", rotulo: "RISC-V", testa: (s) => s.arquitetura.includes("RISC-V") },
|
||||
{ id: "xtensa", rotulo: "Xtensa", testa: (s) => !s.arquitetura.includes("RISC-V") },
|
||||
{ id: "matter", rotulo: "Matter", testa: (s) => s.matter === "Sim" },
|
||||
{ id: "ia", rotulo: "Aceleração de IA", testa: (s) => Boolean(s.aceleradores_ia) },
|
||||
];
|
||||
|
||||
/** Marcador de segurança: o recurso que diferencia a série, não o que todas têm. */
|
||||
function nivelSeguranca(serie) {
|
||||
const seg = serie.seguranca || {};
|
||||
if (seg.key_manager === "Sim") return "Key Manager";
|
||||
if (String(seg.ecdsa).startsWith("Sim")) return "ECDSA em hardware";
|
||||
if (String(seg.ecc).startsWith("Sim")) return "ECC em hardware";
|
||||
if (String(seg.aes).startsWith("AES")) return "AES + SHA";
|
||||
return "Só SHA";
|
||||
}
|
||||
|
||||
const sim = (v) => !String(v).includes("Não");
|
||||
|
||||
export default function Series() {
|
||||
const [filtro, setFiltro] = useState("todas");
|
||||
const todas = Object.entries(seriesData);
|
||||
const ativo = FILTROS.find((f) => f.id === filtro);
|
||||
const series = useMemo(() => todas.filter(([, s]) => ativo.testa(s)), [todas, ativo]);
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
<Header />
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Séries" }]}
|
||||
icon={Compass}
|
||||
label={`${todas.length} famílias da Espressif`}
|
||||
title="Séries ESP32"
|
||||
lede="Cada série foi desenhada para um tipo de projeto, do sensor a bateria ao acelerador de IA. Abra a ficha para ver pinagem, periféricos e segurança."
|
||||
/>
|
||||
|
||||
<section className="shell pt-10 sm:pt-12" aria-label="Lista de séries">
|
||||
<div role="group" aria-label="Filtrar séries" className="flex flex-wrap gap-2">
|
||||
{FILTROS.map((f) => (
|
||||
<button key={f.id} type="button" aria-pressed={filtro === f.id} onClick={() => setFiltro(f.id)} className="chip-btn">
|
||||
{f.rotulo}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<p role="status" aria-live="polite" className="mt-4 text-sm text-muted">
|
||||
{series.length} {series.length === 1 ? "série" : "séries"}
|
||||
</p>
|
||||
|
||||
<div className="mt-4 grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{series.map(([key, serie]) => {
|
||||
const riscv = serie.arquitetura.includes("RISC-V");
|
||||
const fatos = [
|
||||
["Núcleos", serie.nucleos],
|
||||
["Frequência", serie.frequencia],
|
||||
["SRAM", serie.memoria_sram],
|
||||
["Wi-Fi", sim(serie.wifi) ? "Sim" : "Não"],
|
||||
["Bluetooth", serie.bluetooth === "Não" ? "Não" : "Sim"],
|
||||
serie.consumo_energia?.deep_sleep ? ["Deep sleep", serie.consumo_energia.deep_sleep] : null,
|
||||
].filter(Boolean);
|
||||
return (
|
||||
<Link key={key} href={`/series/${key}`} className="card card-interactive group flex flex-col p-5 sm:p-6">
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<h2 className="font-display text-2xl font-semibold tracking-[-0.035em] text-ink">{key}</h2>
|
||||
<span className="chip">{riscv ? "RISC-V" : "Xtensa"}</span>
|
||||
</div>
|
||||
<p className="mt-2 line-clamp-2 min-h-[2.9rem] text-sm leading-relaxed text-muted">{serie.descricao}</p>
|
||||
|
||||
<dl className="mt-5 divide-y divide-line border-y border-line text-sm">
|
||||
{fatos.map(([rotulo, valor]) => (
|
||||
<div key={rotulo} className="flex items-baseline justify-between gap-4 py-2">
|
||||
<dt className="text-muted">{rotulo}</dt>
|
||||
<dd className={`text-right font-medium ${valor === "Não" ? "text-muted" : "text-ink"}`}>{valor}</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
|
||||
<ul className="mt-4 flex flex-1 flex-wrap content-start gap-1.5">
|
||||
{serie.aceleradores_ia && (
|
||||
<li className="chip chip-accent">
|
||||
<Sparkles className="h-3 w-3" aria-hidden="true" />
|
||||
Aceleradores de IA
|
||||
</li>
|
||||
)}
|
||||
<li className="chip">
|
||||
<ShieldCheck className="h-3 w-3 text-accent" aria-hidden="true" />
|
||||
{nivelSeguranca(serie)}
|
||||
</li>
|
||||
{serie.matter === "Sim" && (
|
||||
<li className="chip">
|
||||
<Home className="h-3 w-3 text-accent" aria-hidden="true" />
|
||||
Matter
|
||||
</li>
|
||||
)}
|
||||
{serie.status_documentacao && (
|
||||
<li className="chip">
|
||||
<AlertTriangle className="h-3 w-3 text-gold" aria-hidden="true" />
|
||||
Documentação preliminar
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
|
||||
<span className="mt-5 inline-flex items-center gap-1 text-sm font-medium text-accent">
|
||||
Abrir ficha
|
||||
<ArrowUpRight className="h-4 w-4 transition-transform group-hover:-translate-y-0.5 group-hover:translate-x-0.5" aria-hidden="true" />
|
||||
</span>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="shell section">
|
||||
<div className="panel flex flex-col items-start justify-between gap-6 p-7 sm:p-10 md:flex-row md:items-center">
|
||||
<div className="max-w-2xl">
|
||||
<h2 className="section-title">Ficou em dúvida entre duas séries?</h2>
|
||||
<p className="mt-3 text-base text-muted">
|
||||
O comparador coloca até quatro modelos lado a lado: núcleos, rádio, memória, periféricos e segurança.
|
||||
</p>
|
||||
</div>
|
||||
<Link href="/comparacao" className="btn btn-primary shrink-0">
|
||||
<Scale className="h-4 w-4" aria-hidden="true" />
|
||||
Comparar séries
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
+55
-28
@@ -1,51 +1,78 @@
|
||||
import seriesData from "@/public/series.json";
|
||||
import frameworksData from "@/public/frameworks.json";
|
||||
import { SITE } from "@/lib/seo";
|
||||
import { ENABLED_LOCALES, getLocalizedHref } from "@/i18n/links";
|
||||
|
||||
const LANG_MAP = {
|
||||
pt: "pt-BR",
|
||||
en: "en",
|
||||
es: "es-419",
|
||||
fr: "fr",
|
||||
de: "de",
|
||||
"zh-CN": "zh-CN",
|
||||
};
|
||||
|
||||
/**
|
||||
* Sitemap gerado a partir dos próprios dados do site.
|
||||
*
|
||||
* Antes não existia sitemap nenhum, então o Google só chegava às páginas de
|
||||
* série e de framework se topasse com um link. Como são geradas a partir de
|
||||
* JSON, uma série nova entra aqui sozinha.
|
||||
* Sitemap gerado a partir dos próprios dados do site e dos idiomas ativos.
|
||||
* Inclui URLs apenas para ENABLED_LOCALES, com hreflang/alternates correspondentes.
|
||||
* O livro só entra para a versão em português.
|
||||
*/
|
||||
export default function sitemap() {
|
||||
// Usar uma data de revisão estável evita que todo deploy force o Googlebot
|
||||
// a reprocessar páginas idênticas ao mesmo tempo.
|
||||
const dataRevisao = new Date("2026-08-25T00:00:00.000Z");
|
||||
|
||||
const fixas = [
|
||||
{ caminho: "", prioridade: 1.0, frequencia: "weekly", lastModified: dataRevisao },
|
||||
{ caminho: "/series", prioridade: 0.9, frequencia: "weekly", lastModified: dataRevisao },
|
||||
{ caminho: "/comparacao", prioridade: 0.9, frequencia: "weekly", lastModified: dataRevisao },
|
||||
{ caminho: "/diagnostico", prioridade: 0.9, frequencia: "weekly", lastModified: dataRevisao },
|
||||
{ caminho: "/seletor", prioridade: 0.8, frequencia: "monthly", lastModified: dataRevisao },
|
||||
{ caminho: "/frameworks", prioridade: 0.8, frequencia: "monthly", lastModified: dataRevisao },
|
||||
{ caminho: "/componentes", prioridade: 0.8, frequencia: "weekly", lastModified: dataRevisao },
|
||||
{ caminho: "/livro", prioridade: 0.7, frequencia: "monthly", lastModified: dataRevisao },
|
||||
{ caminho: "/glossario", prioridade: 0.7, frequencia: "monthly", lastModified: dataRevisao },
|
||||
{ caminho: "/catalogo", prioridade: 0.6, frequencia: "weekly", lastModified: dataRevisao },
|
||||
{ caminho: "/sobre", prioridade: 0.4, frequencia: "yearly", lastModified: dataRevisao },
|
||||
{ rota: "", prioridade: 1.0, frequencia: "weekly" },
|
||||
{ rota: "/series", prioridade: 0.9, frequencia: "weekly" },
|
||||
{ rota: "/comparacao", prioridade: 0.9, frequencia: "weekly" },
|
||||
{ rota: "/diagnostico", prioridade: 0.9, frequencia: "weekly" },
|
||||
{ rota: "/seletor", prioridade: 0.8, frequencia: "monthly" },
|
||||
{ rota: "/frameworks", prioridade: 0.8, frequencia: "monthly" },
|
||||
{ rota: "/componentes", prioridade: 0.8, frequencia: "weekly" },
|
||||
{ rota: "/livro", prioridade: 0.7, frequencia: "monthly", apenasPt: true },
|
||||
{ rota: "/glossario", prioridade: 0.7, frequencia: "monthly" },
|
||||
{ rota: "/catalogo", prioridade: 0.6, frequencia: "weekly" },
|
||||
{ rota: "/sobre", prioridade: 0.4, frequencia: "yearly" },
|
||||
];
|
||||
|
||||
const series = Object.keys(seriesData).map((chave) => ({
|
||||
caminho: `/series/${chave}`,
|
||||
rota: `/series/${chave}`,
|
||||
prioridade: 0.9,
|
||||
frequencia: "monthly",
|
||||
lastModified: dataRevisao,
|
||||
}));
|
||||
|
||||
const frameworks = Object.keys(frameworksData).map((chave) => ({
|
||||
caminho: `/frameworks/${encodeURIComponent(chave)}`,
|
||||
rota: `/frameworks/${encodeURIComponent(chave)}`,
|
||||
prioridade: 0.6,
|
||||
frequencia: "monthly",
|
||||
lastModified: dataRevisao,
|
||||
}));
|
||||
|
||||
return [...fixas, ...series, ...frameworks].map(({ caminho, prioridade, frequencia, lastModified }) => ({
|
||||
url: `${SITE.url}${caminho}`,
|
||||
lastModified,
|
||||
changeFrequency: frequencia,
|
||||
priority: prioridade,
|
||||
}));
|
||||
const todasRotas = [...fixas, ...series, ...frameworks];
|
||||
const entries = [];
|
||||
|
||||
for (const item of todasRotas) {
|
||||
for (const loc of ENABLED_LOCALES) {
|
||||
if (item.apenasPt && loc !== "pt") continue;
|
||||
|
||||
const href = getLocalizedHref(`/pt${item.rota}`, loc);
|
||||
const url = `${SITE.url}${href}`;
|
||||
|
||||
const languages = {};
|
||||
for (const l of ENABLED_LOCALES) {
|
||||
if (item.apenasPt && l !== "pt") continue;
|
||||
languages[LANG_MAP[l] || l] = `${SITE.url}${getLocalizedHref(`/pt${item.rota}`, l)}`;
|
||||
}
|
||||
|
||||
entries.push({
|
||||
url,
|
||||
lastModified: dataRevisao,
|
||||
changeFrequency: item.frequencia,
|
||||
priority: item.prioridade,
|
||||
alternates: {
|
||||
languages,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
import { paginaMeta, jsonLd, SITE } from "@/lib/seo";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import Image from "next/image";
|
||||
import GiteaMark from "@/components/GiteaMark";
|
||||
import { ArrowUpRight, Code, Globe, GitCompare, Info, Languages } from "lucide-react";
|
||||
|
||||
const REPOSITORIO = SITE.repositorio;
|
||||
|
||||
|
||||
export const metadata = paginaMeta({
|
||||
titulo: "Sobre o projeto",
|
||||
descricao: "O ESPDocs é uma plataforma independente que reúne a documentação do ecossistema ESP32 em português brasileiro. Saiba como o projeto nasceu e como contribuir.",
|
||||
caminho: "/sobre",
|
||||
keywords: ["ESPDocs", "documentação ESP32 português", "projeto open source ESP32"],
|
||||
});
|
||||
|
||||
export default function Sobre() {
|
||||
const features = [
|
||||
{ icon: Languages, title: "Em português", desc: "Dados técnicos organizados e apresentados em português do Brasil." },
|
||||
{ icon: GitCompare, title: "Comparações visuais", desc: "Tabelas e diagramas para escolher a série certa sem abrir dez datasheets." },
|
||||
{ icon: Globe, title: "Acesso centralizado", desc: "Links diretos para a documentação oficial, repositórios e exemplos." },
|
||||
{ icon: Code, title: "Código aberto", desc: "Contribuições são bem-vindas no Gitea." },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
{/* Metadados E-E-A-T de autoria e organização para o Google */}
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.paginaSobre()) }}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Sobre o Projeto", caminho: "/sobre" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
<Header />
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Sobre" }]}
|
||||
icon={Info}
|
||||
label="Projeto independente"
|
||||
title="Sobre o ESPDocs"
|
||||
lede="Uma plataforma não oficial, em português, que organiza as informações técnicas do ESP32 e leva você à documentação oficial da Espressif. Feita para a comunidade de hardware livre."
|
||||
>
|
||||
<a href={REPOSITORIO} target="_blank" rel="noopener noreferrer" className="btn btn-primary">
|
||||
<GiteaMark className="h-4 w-4" />
|
||||
Ver o repositório
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</PageHero>
|
||||
|
||||
<div className="shell section grid grid-cols-1 gap-10 pt-12 sm:pt-16 lg:grid-cols-[1fr_22rem] lg:gap-14">
|
||||
<div className="min-w-0 max-w-3xl space-y-12">
|
||||
<section aria-labelledby="missao">
|
||||
<h2 id="missao" className="section-title">Missão</h2>
|
||||
<p className="mt-4 text-base leading-relaxed text-muted">
|
||||
Facilitar o acesso e a compreensão do ecossistema ESP32 com uma interface em português que organiza
|
||||
especificações, compara séries, apresenta frameworks e centraliza os links da documentação oficial.
|
||||
O objetivo é economizar o seu tempo no desenvolvimento de firmware e IoT.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="porque">
|
||||
<h2 id="porque" className="section-title">Por que o ESPDocs existe</h2>
|
||||
<p className="mt-4 text-base leading-relaxed text-muted">
|
||||
As informações sobre os ESP32 costumam estar espalhadas entre datasheets densos, manuais de referência
|
||||
(TRM) e repositórios secundários, tudo em inglês. O ESPDocs condensa e estrutura esses dados para a
|
||||
triagem rápida, antes de você aprofundar na engenharia oficial.
|
||||
</p>
|
||||
<ul className="mt-6 grid gap-3 sm:grid-cols-2">
|
||||
{features.map(({ icon: Icon, title, desc }) => (
|
||||
<li key={title} className="card flex items-start gap-4 p-5">
|
||||
<span className="grid h-10 w-10 shrink-0 place-items-center rounded-full bg-accent-soft text-accent">
|
||||
<Icon className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<div>
|
||||
<h3 className="font-semibold text-ink">{title}</h3>
|
||||
<p className="mt-1 text-sm leading-relaxed text-muted">{desc}</p>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="contribuir">
|
||||
<h2 id="contribuir" className="section-title">Como contribuir</h2>
|
||||
<p className="mt-4 text-base leading-relaxed text-muted">
|
||||
Correções de tradução, ajustes em tabelas e novos exemplos de código são muito bem-vindos. O projeto
|
||||
cresce com a comunidade.
|
||||
</p>
|
||||
<ol className="mt-6 space-y-3">
|
||||
{[
|
||||
"Faça o fork do repositório no Gitea.",
|
||||
"Implemente as melhorias e confira as referências técnicas oficiais.",
|
||||
"Abra um Pull Request descrevendo os ajustes feitos.",
|
||||
].map((passo, i) => (
|
||||
<li key={passo} className="card flex items-center gap-4 px-5 py-4">
|
||||
<span className="grid h-8 w-8 shrink-0 place-items-center rounded-full bg-ink text-sm font-semibold text-canvas" aria-hidden="true">
|
||||
{i + 1}
|
||||
</span>
|
||||
<span className="text-sm text-ink-soft sm:text-base">{passo}</span>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="acessibilidade">
|
||||
<h2 id="acessibilidade" className="section-title">Acessibilidade</h2>
|
||||
<p className="mt-4 text-base leading-relaxed text-muted">
|
||||
O ESPDocs prioriza a legibilidade, o contraste alto (nível AAA da WCAG) e a navegação completa por
|
||||
teclado. Se encontrar alguma barreira de leitura ou navegação, abra uma issue no repositório.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<aside className="space-y-5 lg:sticky lg:top-28 lg:self-start" aria-label="Autor e aviso legal">
|
||||
<div className="panel p-6 sm:p-7">
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="grid h-16 w-16 shrink-0 place-items-center rounded-2xl border border-line bg-white">
|
||||
<Image src="/logo.png" alt="" aria-hidden="true" width={48} height={48} className="h-12 w-12 object-contain" />
|
||||
</span>
|
||||
<div>
|
||||
<h2 className="font-display text-lg font-semibold text-ink">Lucas Rayan Guerra</h2>
|
||||
<p className="text-sm text-muted">Criador do Ciência Embarcada</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 space-y-3 text-sm leading-relaxed text-muted">
|
||||
<p>
|
||||
Técnico em Desenvolvimento de Sistemas, estudante de Ciência da Computação na UFRPE e pesquisador de
|
||||
Blockchain e Criptografia.
|
||||
</p>
|
||||
<p>
|
||||
Diretor de Software na Semine AgriTech e palestrante em eventos como o REC'n'Play, compartilha
|
||||
conteúdo sobre hardware, IoT e cibersegurança.
|
||||
</p>
|
||||
</div>
|
||||
<a href="https://cienciaembarcada.com.br" target="_blank" rel="noopener noreferrer" className="btn btn-ghost mt-6 w-full">
|
||||
Visitar o Ciência Embarcada
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="callout callout-warn">
|
||||
<p className="font-semibold text-ink">Aviso legal</p>
|
||||
<p className="mt-1">
|
||||
O ESPDocs é um agregador e organizador. Os manuais e repositórios referenciados pertencem à Espressif
|
||||
Systems. Em projetos críticos ou comerciais, consulte sempre a documentação oficial.
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,8 +1,31 @@
|
||||
"use client";
|
||||
|
||||
import { ArrowUpRight, Award, Check, CircleHelp } from "lucide-react";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
const HEADER_MAP_EN = {
|
||||
"Nome": "Name",
|
||||
"Descrição": "Description",
|
||||
"Série": "Series",
|
||||
"Loja Oficial": "Official Store",
|
||||
"Fabricante": "Manufacturer",
|
||||
"Processador": "Processor",
|
||||
"Memória Flash": "Flash Memory",
|
||||
"PSRAM": "PSRAM",
|
||||
"Conector USB": "USB Connector",
|
||||
"Interface USB": "USB Interface",
|
||||
"Antena": "Antenna",
|
||||
"Bateria": "Battery",
|
||||
"Display": "Display",
|
||||
"Sensores": "Sensors",
|
||||
"Botões": "Buttons",
|
||||
"LEDs": "LEDs",
|
||||
};
|
||||
|
||||
export default function BoardCard({ board }) {
|
||||
const pathname = usePathname() || "";
|
||||
const isEn = pathname === "/en" || pathname.startsWith("/en/");
|
||||
|
||||
const mainFields = ["Nome", "Link", "Imagem", "Loja Oficial"];
|
||||
|
||||
const technicalFields = Object.keys(board).filter((key) => !mainFields.includes(key) && board[key]);
|
||||
@@ -24,20 +47,21 @@ export default function BoardCard({ board }) {
|
||||
{lojaOficial && (
|
||||
<span className="chip chip-accent mb-3 w-fit">
|
||||
<Award className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
Loja oficial
|
||||
{isEn ? "Official store" : "Loja oficial"}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<h3 className="line-clamp-2 font-display text-lg font-semibold leading-snug tracking-[-0.02em] text-ink">
|
||||
{board.Nome || "Placa genérica"}
|
||||
{board.Nome || (isEn ? "Generic board" : "Placa genérica")}
|
||||
</h3>
|
||||
|
||||
{recursos.length > 0 && (
|
||||
<div className="mt-4">
|
||||
<p className="text-xs font-medium text-muted">Recursos embarcados</p>
|
||||
<p className="text-xs font-medium text-muted">{isEn ? "On-board features" : "Recursos embarcados"}</p>
|
||||
<ul className="mt-2 flex flex-wrap gap-1.5">
|
||||
{recursos.map((campo) => {
|
||||
const opcional = valor(campo) === "opcional";
|
||||
const label = isEn ? (HEADER_MAP_EN[campo] || campo) : campo;
|
||||
return (
|
||||
<li key={campo} className={`chip ${opcional ? "text-gold" : "text-ink-soft"}`}>
|
||||
{opcional ? (
|
||||
@@ -45,8 +69,8 @@ export default function BoardCard({ board }) {
|
||||
) : (
|
||||
<Check className="h-3 w-3 text-ok" aria-hidden="true" />
|
||||
)}
|
||||
{campo}
|
||||
{opcional && <span className="sr-only"> (opcional)</span>}
|
||||
{label}
|
||||
{opcional && <span className="sr-only">{isEn ? " (optional)" : " (opcional)"}</span>}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
@@ -56,9 +80,9 @@ export default function BoardCard({ board }) {
|
||||
|
||||
{board.Link && (
|
||||
<a href={board.Link} target="_blank" rel="noopener noreferrer" className="btn btn-primary mt-6 w-full">
|
||||
Ver no AliExpress
|
||||
{isEn ? "View on AliExpress" : "Ver no AliExpress"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
<span className="sr-only"> (abre em nova aba)</span>
|
||||
<span className="sr-only">{isEn ? " (opens in new tab)" : " (abre em nova aba)"}</span>
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
|
||||
+54
-16
@@ -2,8 +2,12 @@
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { Check, Copy, ExternalLink } from "lucide-react";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
export default function CodeExample({ framework }) {
|
||||
const pathname = usePathname() || "";
|
||||
const isEn = pathname === "/en" || pathname.startsWith("/en/");
|
||||
|
||||
const examplesUrl = framework?.exemplos;
|
||||
|
||||
const [sample, setSample] = useState("");
|
||||
@@ -20,18 +24,36 @@ export default function CodeExample({ framework }) {
|
||||
|
||||
const exemploPath = framework.exemplo;
|
||||
if (!exemploPath) {
|
||||
setSample(`// Exemplos completos: ${examplesUrl || "ver repositório"}\n`);
|
||||
setSample(
|
||||
isEn
|
||||
? `// Full examples: ${examplesUrl || "see repository"}\n`
|
||||
: `// Exemplos completos: ${examplesUrl || "ver repositório"}\n`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const url = exemploPath.startsWith("/") ? exemploPath : `/${exemploPath}`;
|
||||
// Se locale for en, busca primeiro em /exemplos/en/
|
||||
let url = exemploPath.startsWith("/") ? exemploPath : `/${exemploPath}`;
|
||||
if (isEn && url.startsWith("/exemplos/") && !url.startsWith("/exemplos/en/")) {
|
||||
url = url.replace("/exemplos/", "/exemplos/en/");
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
setLoading(true);
|
||||
|
||||
fetch(url)
|
||||
.then((res) => {
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||
if (!res.ok) {
|
||||
// Fallback para o arquivo original se não achar a versão traduzida
|
||||
const fallbackUrl = exemploPath.startsWith("/") ? exemploPath : `/${exemploPath}`;
|
||||
if (fallbackUrl !== url) {
|
||||
return fetch(fallbackUrl).then((r2) => {
|
||||
if (!r2.ok) throw new Error(`HTTP ${r2.status}`);
|
||||
return r2.text();
|
||||
});
|
||||
}
|
||||
throw new Error(`HTTP ${res.status}`);
|
||||
}
|
||||
return res.text();
|
||||
})
|
||||
.then((text) => {
|
||||
@@ -39,14 +61,22 @@ export default function CodeExample({ framework }) {
|
||||
if (text && text.trim().length > 0) {
|
||||
setSample(text);
|
||||
} else {
|
||||
setSample("// O arquivo de exemplo está vazio. Consulte o repositório oficial.\n");
|
||||
setError("arquivo vazio");
|
||||
setSample(
|
||||
isEn
|
||||
? "// The example file is empty. Refer to the official repository.\n"
|
||||
: "// O arquivo de exemplo está vazio. Consulte o repositório oficial.\n"
|
||||
);
|
||||
setError(isEn ? "empty file" : "arquivo vazio");
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
if (cancelled) return;
|
||||
setSample("// Não foi possível carregar o exemplo.\n// Consulte o repositório oficial para exemplos completos.\n");
|
||||
setError(err.message || "falha ao carregar");
|
||||
setSample(
|
||||
isEn
|
||||
? "// Could not load example.\n// Refer to official repository for complete examples.\n"
|
||||
: "// Não foi possível carregar o exemplo.\n// Consulte o repositório oficial para exemplos completos.\n"
|
||||
);
|
||||
setError(err.message || (isEn ? "load failure" : "falha ao carregar"));
|
||||
})
|
||||
.finally(() => {
|
||||
if (!cancelled) setLoading(false);
|
||||
@@ -55,7 +85,7 @@ export default function CodeExample({ framework }) {
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [framework?.exemplo, framework?.exemplos]);
|
||||
}, [framework?.exemplo, framework?.exemplos, isEn]);
|
||||
|
||||
const lines = (sample || "").replace(/\n$/, "").split("\n");
|
||||
|
||||
@@ -71,20 +101,26 @@ export default function CodeExample({ framework }) {
|
||||
<div className="card p-5 sm:p-7">
|
||||
<div className="flex flex-wrap items-start justify-between gap-4">
|
||||
<div>
|
||||
<h2 className="font-display text-xl font-semibold tracking-[-0.03em] text-ink">Exemplo de código</h2>
|
||||
<p className="mt-1 text-sm text-muted">Trecho de partida em {framework?.linguagem}. Ajuste pinos e configuração à sua placa.</p>
|
||||
<h2 className="font-display text-xl font-semibold tracking-[-0.03em] text-ink">
|
||||
{isEn ? "Code example" : "Exemplo de código"}
|
||||
</h2>
|
||||
<p className="mt-1 text-sm text-muted">
|
||||
{isEn
|
||||
? `Starter snippet in ${framework?.linguagem}. Adjust pins and configuration for your board.`
|
||||
: `Trecho de partida em ${framework?.linguagem}. Ajuste pinos e configuração à sua placa.`}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<button type="button" onClick={handleCopy} className="btn btn-ghost btn-sm">
|
||||
{copied ? <Check className="h-4 w-4 text-ok" aria-hidden="true" /> : <Copy className="h-4 w-4" aria-hidden="true" />}
|
||||
<span role="status">{copied ? "Copiado" : "Copiar"}</span>
|
||||
<span role="status">{copied ? (isEn ? "Copied" : "Copiado") : (isEn ? "Copy" : "Copiar")}</span>
|
||||
</button>
|
||||
{examplesUrl && (
|
||||
<a href={examplesUrl} target="_blank" rel="noopener noreferrer" className="btn btn-ghost btn-sm">
|
||||
Mais exemplos
|
||||
{isEn ? "More examples" : "Mais exemplos"}
|
||||
<ExternalLink className="h-4 w-4" aria-hidden="true" />
|
||||
<span className="sr-only"> (abre em nova aba)</span>
|
||||
<span className="sr-only">{isEn ? " (opens in new tab)" : " (abre em nova aba)"}</span>
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
@@ -93,9 +129,9 @@ export default function CodeExample({ framework }) {
|
||||
<div className="code-panel mt-5" aria-busy={loading}>
|
||||
<div className="flex items-center justify-between border-b border-white/10 px-4 py-2.5 text-xs text-[#a6afbd]">
|
||||
<span className="font-mono">{framework?.nome}</span>
|
||||
<span>{loading ? "Carregando exemplo…" : framework?.linguagem}</span>
|
||||
<span>{loading ? (isEn ? "Loading example…" : "Carregando exemplo…") : framework?.linguagem}</span>
|
||||
</div>
|
||||
<pre tabIndex={0} aria-label={`Código de exemplo em ${framework?.linguagem}`}>
|
||||
<pre tabIndex={0} aria-label={isEn ? `Code example in ${framework?.linguagem}` : `Código de exemplo em ${framework?.linguagem}`}>
|
||||
<code>
|
||||
{lines.map((line, idx) => (
|
||||
<span key={idx} className="flex">
|
||||
@@ -109,7 +145,9 @@ export default function CodeExample({ framework }) {
|
||||
|
||||
{error && (
|
||||
<p role="alert" className="callout callout-warn mt-4">
|
||||
Não foi possível carregar o exemplo local ({error}). Use “Mais exemplos” para ver o código oficial.
|
||||
{isEn
|
||||
? `Could not load local example (${error}). Use “More examples” to view official code.`
|
||||
: `Não foi possível carregar o exemplo local (${error}). Use “Mais exemplos” para ver o código oficial.`}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -33,6 +33,29 @@ const FILTER_CATEGORIES = [
|
||||
{ id: "Antena", name: "Antena", color: "#06b6d4" }, // cyan
|
||||
];
|
||||
|
||||
const FILTER_CATEGORIES_EN = [
|
||||
{ id: "All", name: "All", color: "#8b5cf6" },
|
||||
{ id: "GND", name: "Ground (GND)", color: "#64748b" },
|
||||
{ id: "Power", name: "Power", color: "#ef4444" },
|
||||
{ id: "GPIO", name: "GPIO", color: "#22c55e" },
|
||||
{ id: "Low Power", name: "LP GPIO", color: "#f59e0b" },
|
||||
{ id: "ADC", name: "ADC", color: "#ec4899" },
|
||||
{ id: "DAC", name: "DAC", color: "#a855f7" },
|
||||
{ id: "Touch", name: "Touch", color: "#06b6d4" },
|
||||
{ id: "UART", name: "UART", color: "#3b82f6" },
|
||||
{ id: "SPI", name: "SPI", color: "#f43f5e" },
|
||||
{ id: "USB", name: "USB", color: "#a855f7" },
|
||||
{ id: "Clock", name: "Clock", color: "#eab308" },
|
||||
{ id: "JTAG", name: "JTAG", color: "#6366f1" },
|
||||
{ id: "Strapping", name: "Boot mode", color: "#dc2626" },
|
||||
{ id: "DSI", name: "Display (DSI)", color: "#f97316" },
|
||||
{ id: "CSI", name: "Camera (CSI)", color: "#14b8a6" },
|
||||
{ id: "Ethernet", name: "Ethernet", color: "#0284c7" },
|
||||
{ id: "SD", name: "SD Card", color: "#10b981" },
|
||||
{ id: "I2C", name: "I2C", color: "#f59e0b" },
|
||||
{ id: "Antena", name: "Antenna", color: "#06b6d4" },
|
||||
];
|
||||
|
||||
const type_colors = {
|
||||
power: "#ef4444", // high-voltage red
|
||||
ground: "#64748b", // slate gray
|
||||
@@ -58,6 +81,7 @@ export default function ConnectionsDiagram(props) {
|
||||
function ConnectionsDiagramInner({ connections, serie }) {
|
||||
const params = useSearchParams();
|
||||
const pathname = usePathname();
|
||||
const isEn = pathname?.startsWith("/en");
|
||||
const router = useRouter();
|
||||
const pinosFiltro = useMemo(() => new Set((params.get("pinos") ?? "").split(",").filter(Boolean)), [params]);
|
||||
const motivoFiltro = params.get("motivo") ?? "";
|
||||
@@ -69,6 +93,8 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
const dialogRef = useRef(null);
|
||||
const gatilhoRef = useRef(null);
|
||||
|
||||
const filterCategories = isEn ? FILTER_CATEGORIES_EN : FILTER_CATEGORIES;
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
@@ -84,11 +110,18 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
};
|
||||
|
||||
const getCategoryColor = (category) => {
|
||||
const filter = FILTER_CATEGORIES.find((f) => f.id === category);
|
||||
const filter = filterCategories.find((f) => f.id === category);
|
||||
return filter?.color || "#64748b";
|
||||
};
|
||||
|
||||
const nomeCategoria = (cat) => (cat === "Strapping" ? "Inicialização" : cat);
|
||||
const nomeCategoria = (cat) => {
|
||||
if (cat === "Strapping") return isEn ? "Boot mode" : "Inicialização";
|
||||
if (isEn) {
|
||||
const found = FILTER_CATEGORIES_EN.find((f) => f.id === cat);
|
||||
if (found) return found.name;
|
||||
}
|
||||
return cat;
|
||||
};
|
||||
|
||||
const visibleConnections = useMemo(() => connections.filter(isConnectionVisible), [connections, activeFilter, searchQuery, pinosFiltro]);
|
||||
|
||||
@@ -142,8 +175,12 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
return (
|
||||
<div className="px-4 py-14 text-center">
|
||||
<Sliders className="mx-auto h-10 w-10 text-muted" aria-hidden="true" />
|
||||
<p className="mt-4 font-display text-xl font-semibold text-ink">Diagrama de conexões indisponível</p>
|
||||
<p className="mt-1 text-sm text-muted">Este modelo ainda não tem um mapa detalhado de conexões e barramentos.</p>
|
||||
<p className="mt-4 font-display text-xl font-semibold text-ink">
|
||||
{isEn ? "Pinout diagram unavailable" : "Diagrama de conexões indisponível"}
|
||||
</p>
|
||||
<p className="mt-1 text-sm text-muted">
|
||||
{isEn ? "This model does not yet have a detailed pinout and bus map." : "Este modelo ainda não tem um mapa detalhado de conexões e barramentos."}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -153,59 +190,71 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h2 className="font-display text-xl font-semibold tracking-[-0.03em] text-ink">Diagrama de conexões interativo</h2>
|
||||
<h2 className="font-display text-xl font-semibold tracking-[-0.03em] text-ink">
|
||||
{isEn ? "Interactive pinout diagram" : "Diagrama de conexões interativo"}
|
||||
</h2>
|
||||
<p className="mt-2 max-w-3xl text-sm leading-relaxed text-muted">
|
||||
Todas as conexões e a multiplexação do {serie.nome_completo}. Busque por nome ou número, filtre por função e abra um pino para ver os detalhes.
|
||||
{isEn ? (
|
||||
`All connections and multiplexing for the ${serie.nome_completo}. Search by name or number, filter by function, and open a pin to see details.`
|
||||
) : (
|
||||
`Todas as conexões e a multiplexação do ${serie.nome_completo}. Busque por nome ou número, filtre por função e abra um pino para ver os detalhes.`
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{pinosFiltro.size > 0 && (
|
||||
<div role="status" className="callout flex flex-wrap items-center justify-between gap-3">
|
||||
<p className="text-sm text-ink">
|
||||
<strong className="font-semibold">Filtrado pela busca:</strong> {motivoFiltro || "pinos selecionados"} ({pinosFiltro.size}{" "}
|
||||
{pinosFiltro.size === 1 ? "pino" : "pinos"})
|
||||
<strong className="font-semibold">{isEn ? "Filtered by search:" : "Filtrado pela busca:"}</strong> {motivoFiltro || (isEn ? "selected pins" : "pinos selecionados")} ({pinosFiltro.size}{" "}
|
||||
{pinosFiltro.size === 1 ? (isEn ? "pin" : "pino") : (isEn ? "pins" : "pinos")})
|
||||
</p>
|
||||
<button type="button" onClick={mostrarTodos} className="btn btn-ghost btn-sm">
|
||||
Mostrar todos os pinos
|
||||
{isEn ? "Show all pins" : "Mostrar todos os pinos"}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-col gap-3 sm:flex-row">
|
||||
<div className="relative flex-1">
|
||||
<label htmlFor="busca-pino" className="sr-only">Buscar conexão por nome ou número</label>
|
||||
<label htmlFor="busca-pino" className="sr-only">
|
||||
{isEn ? "Search connection by name or number" : "Buscar conexão por nome ou número"}
|
||||
</label>
|
||||
<Search className="pointer-events-none absolute left-4 top-1/2 h-4 w-4 -translate-y-1/2 text-muted" aria-hidden="true" />
|
||||
<input
|
||||
id="busca-pino"
|
||||
type="search"
|
||||
placeholder="Buscar pino (ex.: GPIO1, TXD, XTAL)"
|
||||
placeholder={isEn ? "Search pin (e.g.: GPIO1, TXD, XTAL)" : "Buscar pino (ex.: GPIO1, TXD, XTAL)"}
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
autoComplete="off"
|
||||
className="field pl-11 pr-4 text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div role="group" aria-label="Modo de exibição" className="flex gap-2">
|
||||
<div role="group" aria-label={isEn ? "Display mode" : "Modo de exibição"} className="flex gap-2">
|
||||
<button type="button" onClick={() => setViewMode("grid")} aria-pressed={viewMode === "grid"} className="chip-btn">
|
||||
<Grid className="h-4 w-4" aria-hidden="true" />
|
||||
Grade
|
||||
{isEn ? "Grid" : "Grade"}
|
||||
</button>
|
||||
<button type="button" onClick={() => setViewMode("list")} aria-pressed={viewMode === "list"} className="chip-btn">
|
||||
<List className="h-4 w-4" aria-hidden="true" />
|
||||
Lista
|
||||
{isEn ? "List" : "Lista"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<h3 className="text-sm font-semibold text-ink">Função do pino</h3>
|
||||
<h3 className="text-sm font-semibold text-ink">{isEn ? "Pin function" : "Função do pino"}</h3>
|
||||
<p role="status" aria-live="polite" className="text-sm text-muted">
|
||||
{visibleConnections.length} de {connections.length} pinos
|
||||
{isEn ? (
|
||||
`${visibleConnections.length} of ${connections.length} pins`
|
||||
) : (
|
||||
`${visibleConnections.length} de ${connections.length} pinos`
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div role="group" aria-label="Filtrar por função" className="mt-3 flex flex-wrap gap-2">
|
||||
{FILTER_CATEGORIES.map((filter) => {
|
||||
<div role="group" aria-label={isEn ? "Filter by function" : "Filtrar por função"} className="mt-3 flex flex-wrap gap-2">
|
||||
{filterCategories.map((filter) => {
|
||||
const isActive = activeFilter === filter.id;
|
||||
const count = connections.filter((c) => (filter.id === "All" ? true : c.categorias.includes(filter.id))).length;
|
||||
if (count === 0 && !isActive) return null; // filtros que não se aplicam a este chip
|
||||
@@ -223,8 +272,8 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
{visibleConnections.length === 0 ? (
|
||||
<div className="rounded-2xl border border-dashed border-line-strong px-6 py-12 text-center">
|
||||
<Search className="mx-auto h-8 w-8 text-muted" aria-hidden="true" />
|
||||
<p className="mt-3 font-semibold text-ink">Nenhuma conexão encontrada</p>
|
||||
<p className="mt-1 text-sm text-muted">Ajuste a busca ou volte para todas as funções.</p>
|
||||
<p className="mt-3 font-semibold text-ink">{isEn ? "No connections found" : "Nenhuma conexão encontrada"}</p>
|
||||
<p className="mt-1 text-sm text-muted">{isEn ? "Adjust your search or return to all functions." : "Ajuste a busca ou volte para todas as funções."}</p>
|
||||
<button type="button" onClick={() => { setActiveFilter("All"); setSearchQuery(""); if (pinosFiltro.size) mostrarTodos(); }} className="btn btn-primary btn-sm mt-5">
|
||||
Limpar busca e filtros
|
||||
</button>
|
||||
@@ -239,7 +288,7 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
type="button"
|
||||
onClick={(e) => abrir(connection, e)}
|
||||
aria-haspopup="dialog"
|
||||
aria-label={`Pino ${connection.nome}, número ${connection.numero}${connection.avisos ? ", com restrições de uso" : ""}`}
|
||||
aria-label={isEn ? `Pin ${connection.nome}, number ${connection.numero}${connection.avisos ? ", with usage restrictions" : ""}` : `Pino ${connection.nome}, número ${connection.numero}${connection.avisos ? ", com restrições de uso" : ""}`}
|
||||
className="flex w-full flex-col items-center rounded-xl border border-line bg-surface p-3 transition-colors hover:bg-surface-2"
|
||||
>
|
||||
<span
|
||||
@@ -267,13 +316,15 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
) : (
|
||||
<div className="overflow-x-auto rounded-xl border border-line">
|
||||
<table className="w-full min-w-[40rem] border-collapse text-left text-sm">
|
||||
<caption className="sr-only">Conexões do {serie.nome_completo}</caption>
|
||||
<caption className="sr-only">
|
||||
{isEn ? `Connections of ${serie.nome_completo}` : `Conexões do ${serie.nome_completo}`}
|
||||
</caption>
|
||||
<thead>
|
||||
<tr className="border-b border-line bg-surface-2 text-muted">
|
||||
<th scope="col" className="px-4 py-3 font-medium">Pino</th>
|
||||
<th scope="col" className="px-4 py-3 font-medium">Nome</th>
|
||||
<th scope="col" className="px-4 py-3 font-medium">Funções</th>
|
||||
<th scope="col" className="px-4 py-3 font-medium">Uso</th>
|
||||
<th scope="col" className="px-4 py-3 font-medium">{isEn ? "Pin" : "Pino"}</th>
|
||||
<th scope="col" className="px-4 py-3 font-medium">{isEn ? "Name" : "Nome"}</th>
|
||||
<th scope="col" className="px-4 py-3 font-medium">{isEn ? "Functions" : "Funções"}</th>
|
||||
<th scope="col" className="px-4 py-3 font-medium">{isEn ? "Usage" : "Uso"}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-line">
|
||||
@@ -286,7 +337,7 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
type="button"
|
||||
onClick={(e) => abrir(connection, e)}
|
||||
aria-haspopup="dialog"
|
||||
aria-label={`Abrir detalhes do pino ${connection.nome}, número ${connection.numero}`}
|
||||
aria-label={isEn ? `Open pin details for ${connection.nome}, number ${connection.numero}` : `Abrir detalhes do pino ${connection.nome}, número ${connection.numero}`}
|
||||
className="grid h-11 w-11 place-items-center rounded-full border-2 bg-surface text-sm font-semibold tabular-nums text-ink hover:bg-surface-2"
|
||||
style={{ borderColor: baseColor }}
|
||||
>
|
||||
@@ -301,12 +352,12 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
{connection.avisos ? (
|
||||
<span className="inline-flex items-center gap-1.5 font-medium text-danger">
|
||||
<AlertTriangle className="h-4 w-4" aria-hidden="true" />
|
||||
Restrito
|
||||
{isEn ? "Restricted" : "Restrito"}
|
||||
</span>
|
||||
) : (
|
||||
<span className="inline-flex items-center gap-1.5 text-ok">
|
||||
<CheckCircle className="h-4 w-4" aria-hidden="true" />
|
||||
Livre
|
||||
{isEn ? "Free" : "Livre"}
|
||||
</span>
|
||||
)}
|
||||
</td>
|
||||
@@ -322,10 +373,19 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
<div className="callout callout-warn flex items-start gap-3">
|
||||
<AlertTriangle className="mt-0.5 h-5 w-5 shrink-0 text-gold" aria-hidden="true" />
|
||||
<div>
|
||||
<p className="font-semibold text-ink">Notas sobre a pinagem</p>
|
||||
<p className="font-semibold text-ink">{isEn ? "Pinout notes" : "Notas sobre a pinagem"}</p>
|
||||
<ul className="mt-1 list-disc space-y-1 pl-5">
|
||||
<li>Pinos com o ícone de alerta têm papel especial no boot ou limitações analógicas. Abra o pino para ver os detalhes.</li>
|
||||
<li>Isole os circuitos de toque capacitivo de pinos com ruído de RF acoplado.</li>
|
||||
{isEn ? (
|
||||
<>
|
||||
<li>Pins with a warning icon have special boot roles or analog limitations. Open the pin to see details.</li>
|
||||
<li>Isolate capacitive touch traces from coupled RF noise.</li>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<li>Pinos com o ícone de alerta têm papel especial no boot ou limitações analógicas. Abra o pino para ver os detalhes.</li>
|
||||
<li>Isole os circuitos de toque capacitivo de pinos com ruído de RF acoplado.</li>
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -353,10 +413,12 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
<h3 id="modal-title" className="break-words font-display text-2xl font-semibold tracking-[-0.03em] text-ink">
|
||||
{selectedConnection.nome}
|
||||
</h3>
|
||||
<p className="text-sm text-muted">Pino físico {selectedConnection.numero}</p>
|
||||
<p className="text-sm text-muted">
|
||||
{isEn ? `Physical pin ${selectedConnection.numero}` : `Pino físico ${selectedConnection.numero}`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" onClick={fechar} aria-label="Fechar detalhes do pino" className="grid h-11 w-11 shrink-0 place-items-center rounded-full text-muted transition-colors hover:bg-surface-2 hover:text-ink">
|
||||
<button type="button" onClick={fechar} aria-label={isEn ? "Close pin details" : "Fechar detalhes do pino"} className="grid h-11 w-11 shrink-0 place-items-center rounded-full text-muted transition-colors hover:bg-surface-2 hover:text-ink">
|
||||
<X className="h-5 w-5" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
@@ -364,7 +426,7 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
<div className="flex-1 space-y-6 overflow-y-auto p-5 sm:p-7">
|
||||
{selectedConnection.categorias.length > 0 && (
|
||||
<section>
|
||||
<h4 className="text-sm font-semibold text-ink">Categorias</h4>
|
||||
<h4 className="text-sm font-semibold text-ink">{isEn ? "Categories" : "Categorias"}</h4>
|
||||
<ul className="mt-3 flex flex-wrap gap-2">
|
||||
{selectedConnection.categorias.map((cat) => (
|
||||
<li key={cat} className="chip">
|
||||
@@ -380,7 +442,7 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
<section>
|
||||
<h4 className="flex items-center gap-2 text-sm font-semibold text-ink">
|
||||
<Zap className="h-4 w-4 text-danger" aria-hidden="true" />
|
||||
Domínio de alimentação
|
||||
{isEn ? "Power domain" : "Domínio de alimentação"}
|
||||
</h4>
|
||||
<ul className="tile mt-3 space-y-2">
|
||||
{selectedConnection.alimentacao.map((source) => (
|
||||
@@ -391,7 +453,7 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
)}
|
||||
|
||||
<section>
|
||||
<h4 className="text-sm font-semibold text-ink">Funções disponíveis</h4>
|
||||
<h4 className="text-sm font-semibold text-ink">{isEn ? "Available functions" : "Funções disponíveis"}</h4>
|
||||
<ul className="tile mt-3 grid gap-2.5 sm:grid-cols-2">
|
||||
{selectedConnection.funcoes.map((func) => (
|
||||
<li key={func} className="flex items-center gap-2.5 text-sm text-ink-soft">
|
||||
@@ -406,7 +468,7 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
<section className="callout callout-danger">
|
||||
<h4 className="flex items-center gap-2 font-semibold text-ink">
|
||||
<AlertTriangle className="h-4 w-4 text-danger" aria-hidden="true" />
|
||||
Avisos de engenharia
|
||||
{isEn ? "Engineering notes" : "Avisos de engenharia"}
|
||||
</h4>
|
||||
<ul className="mt-2 list-disc space-y-1.5 pl-5">
|
||||
{selectedConnection.avisos.map((aviso) => (
|
||||
@@ -418,7 +480,9 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
</div>
|
||||
|
||||
<div className="border-t border-line p-4 sm:px-7">
|
||||
<button type="button" onClick={fechar} className="btn btn-primary w-full">Fechar</button>
|
||||
<button type="button" onClick={fechar} className="btn btn-primary w-full">
|
||||
{isEn ? "Close" : "Fechar"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
|
||||
+102
-42
@@ -1,10 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import Logo from "@/components/Logo";
|
||||
import GiteaMark from "@/components/GiteaMark";
|
||||
import { ArrowUpRight } from "lucide-react";
|
||||
import { SITE } from "@/lib/seo";
|
||||
import { LOCALES, getLocalizedHref } from "@/i18n/links";
|
||||
|
||||
const COLUMNS = [
|
||||
const COLUMNS_PT = [
|
||||
{
|
||||
title: "Explorar",
|
||||
links: [
|
||||
@@ -34,58 +38,114 @@ const COLUMNS = [
|
||||
},
|
||||
];
|
||||
|
||||
const COLUMNS_EN = [
|
||||
{
|
||||
title: "Explore",
|
||||
links: [
|
||||
{ href: "/series", label: "ESP32 Series" },
|
||||
{ href: "/comparacao", label: "Comparator" },
|
||||
{ href: "/catalogo", label: "Board Catalog" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Tools",
|
||||
links: [
|
||||
{ href: "/seletor", label: "Smart Selector" },
|
||||
{ href: "/diagnostico", label: "Diagnostics" },
|
||||
{ href: "/componentes", label: "Component Registry" },
|
||||
{ href: "/frameworks", label: "Frameworks & SDKs" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Project",
|
||||
links: [
|
||||
{ href: "/sobre", label: "About ESPDocs" },
|
||||
{ href: "/glossario", label: "Glossary" },
|
||||
{ href: SITE.repositorio, label: "Repository", external: true },
|
||||
{ href: `${SITE.repositorio}/issues`, label: "Report an issue", external: true },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default function Footer() {
|
||||
const pathname = usePathname() || "";
|
||||
const year = new Date().getFullYear();
|
||||
|
||||
const currentLocale =
|
||||
LOCALES.find((l) => pathname === `/${l.code}` || pathname.startsWith(`/${l.code}/`))?.code || "pt";
|
||||
const isPt = currentLocale === "pt";
|
||||
|
||||
const getLinkHref = (href) => getLocalizedHref(`/${currentLocale}${href}`, currentLocale);
|
||||
|
||||
const columns = isPt
|
||||
? COLUMNS_PT.map((column) => ({
|
||||
...column,
|
||||
links: column.links.filter((link) => link.href !== "/livro" || isPt),
|
||||
}))
|
||||
: COLUMNS_EN;
|
||||
|
||||
return (
|
||||
<footer className="mt-20 border-t border-line md:mt-28" aria-label="Rodapé do ESPDocs">
|
||||
<footer className="mt-20 border-t border-line md:mt-28" aria-label={isPt ? "Rodapé do ESPDocs" : "ESPDocs footer"}>
|
||||
<div className="shell py-14 md:py-20">
|
||||
<div className="grid gap-12 lg:grid-cols-[1.1fr_2fr]">
|
||||
<div>
|
||||
<Link href="/" className="inline-flex min-h-11 items-center gap-2.5" aria-label="ESPDocs, página inicial">
|
||||
<Link href={getLinkHref("/")} className="inline-flex min-h-11 items-center gap-2.5" aria-label={isPt ? "ESPDocs, página inicial" : "ESPDocs, homepage"}>
|
||||
<Logo className="h-7 w-7" />
|
||||
<span className="font-display text-2xl font-semibold tracking-[-0.045em] text-ink">ESPDocs</span>
|
||||
</Link>
|
||||
<p className="mt-5 max-w-sm text-sm leading-relaxed text-muted">
|
||||
Documentação independente do ecossistema ESP32, escrita em português brasileiro.
|
||||
Dados públicos, curadoria editorial e links para as fontes oficiais.
|
||||
{isPt ? (
|
||||
<>
|
||||
Documentação independente do ecossistema ESP32, escrita em português brasileiro.
|
||||
Dados públicos, curadoria editorial e links para as fontes oficiais.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Independent documentation of the ESP32 ecosystem.
|
||||
Open data, editorial curation, and links to official sources.
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
|
||||
<Link
|
||||
href="/livro"
|
||||
className="group mt-7 grid grid-cols-[3rem_1fr_auto] items-center gap-3.5 rounded-2xl border border-line bg-surface p-3.5 transition-colors duration-300 hover:border-line-strong"
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src={SITE.livroCapa}
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
width={48}
|
||||
height={72}
|
||||
className="h-[72px] w-12 rounded-md object-cover shadow-md"
|
||||
/>
|
||||
<span className="min-w-0">
|
||||
<span className="text-xs font-semibold text-accent">Livro novo</span>
|
||||
<span className="mt-0.5 block font-display text-base font-semibold leading-tight text-ink">Microcontroladores ESP32</span>
|
||||
<span className="mt-1 block text-xs text-muted">Conectividade, eficiência e desempenho</span>
|
||||
</span>
|
||||
<ArrowUpRight className="h-4 w-4 text-faint transition-transform duration-300 group-hover:-translate-y-0.5 group-hover:translate-x-0.5 group-hover:text-accent" aria-hidden="true" />
|
||||
</Link>
|
||||
{isPt && (
|
||||
<>
|
||||
<Link
|
||||
href="/pt/livro"
|
||||
className="group mt-7 grid grid-cols-[3rem_1fr_auto] items-center gap-3.5 rounded-2xl border border-line bg-surface p-3.5 transition-colors duration-300 hover:border-line-strong"
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src={SITE.livroCapa}
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
width={48}
|
||||
height={72}
|
||||
className="h-[72px] w-12 rounded-md object-cover shadow-md"
|
||||
/>
|
||||
<span className="min-w-0">
|
||||
<span className="text-xs font-semibold text-accent">Livro novo</span>
|
||||
<span className="mt-0.5 block font-display text-base font-semibold leading-tight text-ink">Microcontroladores ESP32</span>
|
||||
<span className="mt-1 block text-xs text-muted">Conectividade, eficiência e desempenho</span>
|
||||
</span>
|
||||
<ArrowUpRight className="h-4 w-4 text-faint transition-transform duration-300 group-hover:-translate-y-0.5 group-hover:translate-x-0.5 group-hover:text-accent" aria-hidden="true" />
|
||||
</Link>
|
||||
|
||||
<div className="mt-4 flex flex-wrap gap-x-5 gap-y-2 text-sm">
|
||||
<a href={SITE.livroAmazon} target="_blank" rel="noopener noreferrer" className="inline-flex min-h-11 items-center gap-1 text-muted transition-colors hover:text-accent">
|
||||
Amazon
|
||||
<ArrowUpRight className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
</a>
|
||||
<a href={SITE.livroUiclap} target="_blank" rel="noopener noreferrer" className="inline-flex min-h-11 items-center gap-1 text-muted transition-colors hover:text-accent">
|
||||
UICLAP
|
||||
<ArrowUpRight className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
<div className="mt-4 flex flex-wrap gap-x-5 gap-y-2 text-sm">
|
||||
<a href={SITE.livroAmazon} target="_blank" rel="noopener noreferrer" className="inline-flex min-h-11 items-center gap-1 text-muted transition-colors hover:text-accent">
|
||||
Amazon
|
||||
<ArrowUpRight className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
</a>
|
||||
<a href={SITE.livroUiclap} target="_blank" rel="noopener noreferrer" className="inline-flex min-h-11 items-center gap-1 text-muted transition-colors hover:text-accent">
|
||||
UICLAP
|
||||
<ArrowUpRight className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-8 sm:grid-cols-4">
|
||||
{COLUMNS.map((column) => (
|
||||
{columns.map((column) => (
|
||||
<nav key={column.title} aria-label={column.title}>
|
||||
<h2 className="text-sm font-semibold text-ink">{column.title}</h2>
|
||||
<ul className="mt-2 space-y-0">
|
||||
@@ -102,7 +162,7 @@ export default function Footer() {
|
||||
<ArrowUpRight className="h-3 w-3" aria-hidden="true" />
|
||||
</a>
|
||||
) : (
|
||||
<Link href={link.href} className="inline-flex min-h-11 min-w-11 items-center text-sm text-muted transition-colors hover:text-accent">
|
||||
<Link href={getLinkHref(link.href)} className="inline-flex min-h-11 min-w-11 items-center text-sm text-muted transition-colors hover:text-accent">
|
||||
{link.label}
|
||||
</Link>
|
||||
)}
|
||||
@@ -113,7 +173,7 @@ export default function Footer() {
|
||||
))}
|
||||
|
||||
<div>
|
||||
<h2 className="text-sm font-semibold text-ink">Autor</h2>
|
||||
<h2 className="text-sm font-semibold text-ink">{isPt ? "Autor" : "Author"}</h2>
|
||||
<p className="mt-4 text-sm leading-relaxed text-muted">
|
||||
Lucas Rayan Guerra
|
||||
<br />
|
||||
@@ -124,7 +184,7 @@ export default function Footer() {
|
||||
href={SITE.repositorio}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Gitea do projeto (abre em nova aba)"
|
||||
aria-label={isPt ? "Gitea do projeto (abre em nova aba)" : "Project Gitea (opens in new tab)"}
|
||||
className="grid h-11 w-11 place-items-center rounded-full border border-line text-ink transition-colors hover:border-line-strong hover:bg-surface"
|
||||
>
|
||||
<GiteaMark className="h-4 w-4" />
|
||||
@@ -133,7 +193,7 @@ export default function Footer() {
|
||||
href={SITE.autorLinkedin}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="LinkedIn do autor (abre em nova aba)"
|
||||
aria-label={isPt ? "LinkedIn do autor (abre em nova aba)" : "Author LinkedIn (opens in new tab)"}
|
||||
className="grid h-11 w-11 place-items-center rounded-full border border-line text-ink transition-colors hover:border-line-strong hover:bg-surface"
|
||||
>
|
||||
<svg className="h-4 w-4" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
@@ -146,7 +206,7 @@ export default function Footer() {
|
||||
</div>
|
||||
|
||||
<div className="mt-14 flex flex-col gap-4 border-t border-line pt-6 text-xs leading-relaxed text-faint md:flex-row md:items-center md:justify-between">
|
||||
<p>© {year} ESPDocs. Projeto independente, sem afiliação com a Espressif Systems.</p>
|
||||
<p>© {year} {isPt ? "ESPDocs. Projeto independente, sem afiliação com a Espressif Systems." : "ESPDocs. Independent project, not affiliated with Espressif Systems."}</p>
|
||||
<p className="flex flex-wrap items-center gap-x-5 gap-y-2">
|
||||
<a href={SITE.blog} target="_blank" rel="noopener noreferrer" className="inline-flex min-h-11 items-center gap-1 transition-colors hover:text-accent">
|
||||
Ciência Embarcada
|
||||
@@ -156,7 +216,7 @@ export default function Footer() {
|
||||
lucasrguerra.dev.br
|
||||
<ArrowUpRight className="h-3 w-3" aria-hidden="true" />
|
||||
</a>
|
||||
<span>Fontes oficiais: Espressif Systems.</span>
|
||||
<span>{isPt ? "Fontes oficiais: Espressif Systems." : "Official sources: Espressif Systems."}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+118
-55
@@ -5,6 +5,8 @@ import { createPortal } from "react-dom";
|
||||
import Link from "next/link";
|
||||
import Logo from "@/components/Logo";
|
||||
import SearchDialog from "@/components/SearchDialog";
|
||||
import LanguageSelector from "@/components/LanguageSelector";
|
||||
import { LOCALES, getLocalizedHref } from "@/i18n/links";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useTheme } from "next-themes";
|
||||
import {
|
||||
@@ -26,7 +28,7 @@ import {
|
||||
AlertTriangle,
|
||||
} from "lucide-react";
|
||||
|
||||
const MENUS = [
|
||||
const MENUS_PT = [
|
||||
{
|
||||
id: "hardware",
|
||||
label: "Hardware",
|
||||
@@ -56,7 +58,37 @@ const MENUS = [
|
||||
},
|
||||
];
|
||||
|
||||
const MOBILE_LINKS = [
|
||||
const MENUS_EN = [
|
||||
{
|
||||
id: "hardware",
|
||||
label: "Hardware",
|
||||
items: [
|
||||
{ href: "/series", label: "ESP32 Series", desc: "12 chips, pinouts and specifications", icon: Cpu },
|
||||
{ href: "/comparacao", label: "Comparator", desc: "Up to four series side by side", icon: Scale },
|
||||
{ href: "/catalogo", label: "Board Catalog", desc: "DevKits, pinouts and where to buy", icon: Box },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "tools",
|
||||
label: "Tools",
|
||||
items: [
|
||||
{ href: "/seletor", label: "Smart Selector", desc: "The right chip for your project", icon: SlidersHorizontal },
|
||||
{ href: "/diagnostico", label: "Diagnostics", desc: "Brownout, bootloop, WDT and more", icon: AlertTriangle },
|
||||
{ href: "/componentes", label: "Component Registry", desc: "Drivers and idf_component.yml manifests", icon: Search },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "library",
|
||||
label: "Library",
|
||||
items: [
|
||||
{ href: "/frameworks", label: "Frameworks & SDKs", desc: "ESP-IDF, Arduino, Rust and Matter", icon: BookOpen },
|
||||
{ href: "/glossario", label: "Technical Glossary", desc: "Terms appearing in datasheets", icon: BookA },
|
||||
{ href: "/sobre", label: "About the Project", desc: "Authorship, method and open source", icon: Sparkles },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const MOBILE_LINKS_PT = [
|
||||
{ href: "/series", label: "Séries ESP32" },
|
||||
{ href: "/comparacao", label: "Comparador" },
|
||||
{ href: "/seletor", label: "Seletor inteligente" },
|
||||
@@ -69,12 +101,28 @@ const MOBILE_LINKS = [
|
||||
{ href: "/sobre", label: "Sobre" },
|
||||
];
|
||||
|
||||
function isActivePath(pathname, href) {
|
||||
return href === "/" ? pathname === "/" : pathname === href || String(pathname).startsWith(`${href}/`);
|
||||
const MOBILE_LINKS_EN = [
|
||||
{ href: "/series", label: "ESP32 Series" },
|
||||
{ href: "/comparacao", label: "Comparator" },
|
||||
{ href: "/seletor", label: "Smart Selector" },
|
||||
{ href: "/diagnostico", label: "Diagnostics" },
|
||||
{ href: "/frameworks", label: "Frameworks & SDKs" },
|
||||
{ href: "/componentes", label: "Component Registry" },
|
||||
{ href: "/glossario", label: "Glossary" },
|
||||
{ href: "/catalogo", label: "Board Catalog" },
|
||||
{ href: "/sobre", label: "About" },
|
||||
];
|
||||
|
||||
function isActivePath(pathname, href, currentLocale) {
|
||||
const localized = getLocalizedHref(`/${currentLocale}${href}`, currentLocale);
|
||||
if (href === "/" || localized === `/${currentLocale}/` || localized === `/${currentLocale}`) {
|
||||
return pathname === `/${currentLocale}` || pathname === `/${currentLocale}/`;
|
||||
}
|
||||
return pathname === localized || String(pathname).startsWith(`${localized}/`);
|
||||
}
|
||||
|
||||
export default function Header() {
|
||||
const pathname = usePathname();
|
||||
const pathname = usePathname() || "";
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [openMenu, setOpenMenu] = useState(null);
|
||||
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||
@@ -82,6 +130,12 @@ export default function Header() {
|
||||
const closeRef = useRef(null);
|
||||
const menuButtonRef = useRef(null);
|
||||
|
||||
const currentLocale =
|
||||
LOCALES.find((l) => pathname === `/${l.code}` || pathname.startsWith(`/${l.code}/`))?.code || "pt";
|
||||
const isPt = currentLocale === "pt";
|
||||
|
||||
const getLinkHref = (href) => getLocalizedHref(`/${currentLocale}${href}`, currentLocale);
|
||||
|
||||
useEffect(() => setMounted(true), []);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -118,18 +172,21 @@ export default function Header() {
|
||||
};
|
||||
}, [drawerOpen]);
|
||||
|
||||
const visibleMobileLinks = isPt ? MOBILE_LINKS_PT : MOBILE_LINKS_EN;
|
||||
const MENUS = isPt ? MENUS_PT : MENUS_EN;
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 z-50 pt-3 sm:pt-4">
|
||||
<div className="shell">
|
||||
<div className="nav-pill flex h-16 items-center justify-between gap-3 rounded-full px-3 sm:px-4">
|
||||
<Link href="/" className="flex min-h-11 shrink-0 items-center gap-2.5 rounded-full pl-1 pr-2" aria-label="ESPDocs, página inicial">
|
||||
<Link href={getLinkHref("/")} className="flex min-h-11 shrink-0 items-center gap-2.5 rounded-full pl-1 pr-2" aria-label={isPt ? "ESPDocs, página inicial" : "ESPDocs, homepage"}>
|
||||
<Logo className="h-[30px] w-[30px]" />
|
||||
<span className="font-display text-[1.3rem] font-semibold leading-none tracking-[-0.045em] text-ink">ESPDocs</span>
|
||||
</Link>
|
||||
|
||||
<nav ref={navRef} className="hidden items-center gap-0.5 lg:flex" aria-label="Navegação principal">
|
||||
<nav ref={navRef} className="hidden items-center gap-0.5 lg:flex" aria-label={isPt ? "Navegação principal" : "Main navigation"}>
|
||||
{MENUS.map((menu) => {
|
||||
const active = menu.items.some((item) => isActivePath(pathname, item.href));
|
||||
const active = menu.items.some((item) => isActivePath(pathname, item.href, currentLocale));
|
||||
const expanded = openMenu === menu.id;
|
||||
return (
|
||||
<div key={menu.id} className="relative">
|
||||
@@ -150,12 +207,13 @@ export default function Header() {
|
||||
>
|
||||
{menu.items.map((item) => {
|
||||
const Icon = item.icon;
|
||||
const localizedHref = getLinkHref(item.href);
|
||||
return (
|
||||
<Link
|
||||
key={item.href}
|
||||
href={item.href}
|
||||
href={localizedHref}
|
||||
className="group flex items-start gap-3 rounded-2xl px-3 py-3 transition-colors hover:bg-surface-2"
|
||||
aria-current={isActivePath(pathname, item.href) ? "page" : undefined}
|
||||
aria-current={isActivePath(pathname, item.href, currentLocale) ? "page" : undefined}
|
||||
>
|
||||
<span className="mt-0.5 grid h-9 w-9 shrink-0 place-items-center rounded-xl bg-accent-soft text-accent transition-colors group-hover:bg-surface">
|
||||
<Icon className="h-4 w-4" aria-hidden="true" />
|
||||
@@ -173,26 +231,29 @@ export default function Header() {
|
||||
);
|
||||
})}
|
||||
|
||||
<Link href="/livro" className={`nav-link ${isActivePath(pathname, "/livro") ? "is-active" : ""}`} aria-current={isActivePath(pathname, "/livro") ? "page" : undefined}>
|
||||
Livro
|
||||
</Link>
|
||||
<Link href="/sobre" className={`nav-link ${isActivePath(pathname, "/sobre") ? "is-active" : ""}`} aria-current={isActivePath(pathname, "/sobre") ? "page" : undefined}>
|
||||
Sobre
|
||||
{isPt && (
|
||||
<Link href={getLinkHref("/livro")} className={`nav-link ${isActivePath(pathname, "/livro", currentLocale) ? "is-active" : ""}`} aria-current={isActivePath(pathname, "/livro", currentLocale) ? "page" : undefined}>
|
||||
Livro
|
||||
</Link>
|
||||
)}
|
||||
<Link href={getLinkHref("/sobre")} className={`nav-link ${isActivePath(pathname, "/sobre", currentLocale) ? "is-active" : ""}`} aria-current={isActivePath(pathname, "/sobre", currentLocale) ? "page" : undefined}>
|
||||
{isPt ? "Sobre" : "About"}
|
||||
</Link>
|
||||
</nav>
|
||||
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Link href="/seletor" className="btn btn-primary btn-sm hidden lg:inline-flex">
|
||||
<Link href={getLinkHref("/seletor")} className="btn btn-primary btn-sm hidden lg:inline-flex">
|
||||
<SlidersHorizontal className="h-4 w-4" aria-hidden="true" />
|
||||
Selecionar chip
|
||||
{isPt ? "Selecionar chip" : "Select chip"}
|
||||
</Link>
|
||||
<SearchDialog />
|
||||
<ThemeToggle />
|
||||
<LanguageSelector />
|
||||
<ThemeToggle isPt={isPt} />
|
||||
<button
|
||||
ref={menuButtonRef}
|
||||
type="button"
|
||||
className="grid h-11 w-11 place-items-center rounded-full border border-line text-ink transition-colors hover:bg-surface-2 lg:hidden"
|
||||
aria-label="Abrir menu de navegação"
|
||||
aria-label={isPt ? "Abrir menu de navegação" : "Open navigation menu"}
|
||||
aria-expanded={drawerOpen}
|
||||
onClick={() => setDrawerOpen(true)}
|
||||
>
|
||||
@@ -215,7 +276,7 @@ export default function Header() {
|
||||
<div
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label="Menu de navegação"
|
||||
aria-label={isPt ? "Menu de navegação" : "Navigation menu"}
|
||||
aria-hidden={!drawerOpen}
|
||||
inert={!drawerOpen}
|
||||
className={`fixed inset-y-0 right-0 z-[101] flex w-[min(23rem,94vw)] flex-col rounded-l-[2rem] border-l border-line bg-canvas transition-transform duration-300 ${
|
||||
@@ -224,52 +285,54 @@ export default function Header() {
|
||||
>
|
||||
<div className="flex items-start justify-between px-5 py-5">
|
||||
<div>
|
||||
<p className="text-xs font-semibold text-muted">Navegação</p>
|
||||
<p className="mt-1 font-display text-2xl font-semibold tracking-[-0.04em] text-ink">Para onde ir</p>
|
||||
<p className="text-xs font-semibold text-muted">{isPt ? "Navegação" : "Navigation"}</p>
|
||||
<p className="mt-1 font-display text-2xl font-semibold tracking-[-0.04em] text-ink">{isPt ? "Para onde ir" : "Where to go"}</p>
|
||||
</div>
|
||||
<button
|
||||
ref={closeRef}
|
||||
type="button"
|
||||
onClick={() => setDrawerOpen(false)}
|
||||
className="grid h-10 w-10 place-items-center rounded-full border border-line text-ink transition-colors hover:bg-surface-2"
|
||||
aria-label="Fechar menu"
|
||||
aria-label={isPt ? "Fechar menu" : "Close menu"}
|
||||
>
|
||||
<X className="h-5 w-5" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="px-4 pb-2">
|
||||
<Link
|
||||
href="/livro"
|
||||
onClick={() => setDrawerOpen(false)}
|
||||
className="group grid grid-cols-[3.25rem_1fr_auto] items-center gap-3 rounded-2xl bg-[#0b0d10] p-3 text-[#f4f6f8] ring-1 ring-white/10"
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src="/livro/capa.jpg"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
width={52}
|
||||
height={78}
|
||||
className="h-[78px] w-[52px] rounded-md object-cover shadow-lg"
|
||||
/>
|
||||
<span className="min-w-0">
|
||||
<span className="text-[0.6875rem] font-semibold text-[#75cdc1]">Livro novo</span>
|
||||
<span className="mt-1 block font-display text-lg font-semibold leading-tight">Microcontroladores ESP32</span>
|
||||
<span className="mt-1 block text-xs text-[#a6afbd]">Conectividade, eficiência e desempenho</span>
|
||||
</span>
|
||||
<ArrowRight className="h-4 w-4 shrink-0 text-[#75cdc1] transition-transform duration-300 group-hover:translate-x-1" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
{isPt && (
|
||||
<div className="px-4 pb-2">
|
||||
<Link
|
||||
href="/pt/livro"
|
||||
onClick={() => setDrawerOpen(false)}
|
||||
className="group grid grid-cols-[3.25rem_1fr_auto] items-center gap-3 rounded-2xl bg-[#0b0d10] p-3 text-[#f4f6f8] ring-1 ring-white/10"
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src="/livro/capa.jpg"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
width={52}
|
||||
height={78}
|
||||
className="h-[78px] w-[52px] rounded-md object-cover shadow-lg"
|
||||
/>
|
||||
<span className="min-w-0">
|
||||
<span className="text-[0.6875rem] font-semibold text-[#75cdc1]">Livro novo</span>
|
||||
<span className="mt-1 block font-display text-lg font-semibold leading-tight">Microcontroladores ESP32</span>
|
||||
<span className="mt-1 block text-xs text-[#a6afbd]">Conectividade, eficiência e desempenho</span>
|
||||
</span>
|
||||
<ArrowRight className="h-4 w-4 shrink-0 text-[#75cdc1] transition-transform duration-300 group-hover:translate-x-1" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<nav className="flex-1 overflow-y-auto px-3 py-2" aria-label="Navegação móvel">
|
||||
{MOBILE_LINKS.map((link) => (
|
||||
<nav className="flex-1 overflow-y-auto px-3 py-2" aria-label={isPt ? "Navegação móvel" : "Mobile navigation"}>
|
||||
{visibleMobileLinks.map((link) => (
|
||||
<Link
|
||||
key={link.href}
|
||||
href={link.href}
|
||||
href={getLinkHref(link.href)}
|
||||
onClick={() => setDrawerOpen(false)}
|
||||
className="group flex min-h-11 items-center justify-between gap-3 rounded-xl px-3 text-sm font-medium text-ink-soft transition-colors hover:bg-surface-2 hover:text-ink"
|
||||
aria-current={isActivePath(pathname, link.href) ? "page" : undefined}
|
||||
aria-current={isActivePath(pathname, link.href, currentLocale) ? "page" : undefined}
|
||||
>
|
||||
{link.label}
|
||||
<ArrowRight className="h-4 w-4 text-faint transition-transform duration-300 group-hover:translate-x-0.5 group-hover:text-accent" aria-hidden="true" />
|
||||
@@ -278,9 +341,9 @@ export default function Header() {
|
||||
</nav>
|
||||
|
||||
<div className="p-4 pt-2">
|
||||
<Link href="/seletor" onClick={() => setDrawerOpen(false)} className="btn btn-primary w-full">
|
||||
<Link href={getLinkHref("/seletor")} onClick={() => setDrawerOpen(false)} className="btn btn-primary w-full">
|
||||
<SlidersHorizontal className="h-4 w-4" aria-hidden="true" />
|
||||
Selecionar meu chip
|
||||
{isPt ? "Selecionar meu chip" : "Select my chip"}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
@@ -291,7 +354,7 @@ export default function Header() {
|
||||
);
|
||||
}
|
||||
|
||||
function ThemeToggle() {
|
||||
function ThemeToggle({ isPt = true }) {
|
||||
const { resolvedTheme, setTheme } = useTheme();
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
@@ -308,8 +371,8 @@ function ThemeToggle() {
|
||||
type="button"
|
||||
onClick={() => setTheme(dark ? "light" : "dark")}
|
||||
className="grid h-11 w-11 place-items-center rounded-full border border-line text-ink transition-colors hover:bg-surface-2"
|
||||
aria-label={dark ? "Ativar tema claro" : "Ativar tema escuro"}
|
||||
title={dark ? "Tema claro" : "Tema escuro"}
|
||||
aria-label={dark ? (isPt ? "Ativar tema claro" : "Switch to light theme") : (isPt ? "Ativar tema escuro" : "Switch to dark theme")}
|
||||
title={dark ? (isPt ? "Tema claro" : "Light theme") : (isPt ? "Tema escuro" : "Dark theme")}
|
||||
>
|
||||
{dark ? <Sun className="h-4 w-4" aria-hidden="true" /> : <Moon className="h-4 w-4" aria-hidden="true" />}
|
||||
</button>
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { ChevronDown, Globe } from "lucide-react";
|
||||
import { LOCALES, getLocalizedHref } from "@/i18n/links";
|
||||
|
||||
export { LOCALES, getLocalizedHref };
|
||||
|
||||
export default function LanguageSelector() {
|
||||
if (LOCALES.length <= 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const pathname = usePathname() || "";
|
||||
const [open, setOpen] = useState(false);
|
||||
const [hash, setHash] = useState("");
|
||||
const containerRef = useRef(null);
|
||||
|
||||
// Detecta locale da URL atual
|
||||
const currentLocaleCode =
|
||||
LOCALES.find((l) => pathname === `/${l.code}` || pathname.startsWith(`/${l.code}/`))?.code || "pt";
|
||||
|
||||
const currentLocale = LOCALES.find((l) => l.code === currentLocaleCode) || LOCALES[0];
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
setHash(window.location.hash || "");
|
||||
}
|
||||
}, [pathname]);
|
||||
|
||||
useEffect(() => {
|
||||
function onPointerDown(e) {
|
||||
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
||||
setOpen(false);
|
||||
}
|
||||
}
|
||||
function onKeyDown(e) {
|
||||
if (e.key === "Escape") {
|
||||
setOpen(false);
|
||||
}
|
||||
}
|
||||
document.addEventListener("mousedown", onPointerDown);
|
||||
document.addEventListener("keydown", onKeyDown);
|
||||
return () => {
|
||||
document.removeEventListener("mousedown", onPointerDown);
|
||||
document.removeEventListener("keydown", onKeyDown);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleSelect = (code) => {
|
||||
if (typeof document !== "undefined") {
|
||||
document.cookie = `NEXT_LOCALE=${code}; path=/; max-age=31536000; SameSite=Lax`;
|
||||
}
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div ref={containerRef} className="relative">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen(!open)}
|
||||
className="flex h-11 min-w-[44px] items-center gap-1.5 rounded-full border border-line bg-surface px-3 text-sm font-semibold text-ink transition-colors hover:bg-surface-2 focus-visible:outline-2 focus-visible:outline-accent"
|
||||
aria-haspopup="listbox"
|
||||
aria-expanded={open}
|
||||
aria-label={currentLocaleCode === "en" ? `Current language: ${currentLocale.label}. Click to switch language.` : `Idioma atual: ${currentLocale.label}. Clique para trocar de idioma.`}
|
||||
title={currentLocaleCode === "en" ? `Language: ${currentLocale.label}` : `Idioma: ${currentLocale.label}`}
|
||||
>
|
||||
<Globe className="h-4 w-4 text-muted" aria-hidden="true" />
|
||||
<span className="font-semibold">{currentLocale.short}</span>
|
||||
<ChevronDown
|
||||
className={`h-3 w-3 text-muted transition-transform duration-200 ${open ? "rotate-180" : ""}`}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</button>
|
||||
|
||||
{open && (
|
||||
<div
|
||||
role="listbox"
|
||||
aria-label={currentLocaleCode === "en" ? "Available languages" : "Idiomas disponíveis"}
|
||||
className="absolute right-0 top-full mt-2 w-48 rounded-2xl border border-line bg-surface p-1.5 shadow-[0_24px_60px_-20px_rgba(15,23,42,0.35)] dark:shadow-[0_24px_60px_-20px_rgba(0,0,0,0.8)] z-50"
|
||||
>
|
||||
{LOCALES.map((loc) => {
|
||||
const isActive = loc.code === currentLocaleCode;
|
||||
const href = `${getLocalizedHref(pathname, loc.code)}${hash}`;
|
||||
|
||||
return (
|
||||
<a
|
||||
key={loc.code}
|
||||
href={href}
|
||||
lang={loc.lang}
|
||||
hrefLang={loc.lang}
|
||||
role="option"
|
||||
aria-selected={isActive}
|
||||
aria-current={isActive ? "true" : undefined}
|
||||
onClick={() => handleSelect(loc.code)}
|
||||
className={`flex min-h-[44px] items-center justify-between rounded-xl px-3 py-2 text-sm transition-colors ${
|
||||
isActive
|
||||
? "bg-accent-soft text-accent font-semibold"
|
||||
: "text-ink-soft hover:bg-surface-2 hover:text-ink"
|
||||
}`}
|
||||
>
|
||||
<span>{loc.label}</span>
|
||||
<span className={`text-xs ${isActive ? "text-accent" : "text-muted"}`}>
|
||||
{loc.short}
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
+21
-4
@@ -5,14 +5,31 @@ import Link from "next/link";
|
||||
* e ações. Mesma voz da /livro e da home, para que nenhuma página pareça
|
||||
* de outro produto.
|
||||
*/
|
||||
export default function PageHero({ trail = [], icon: Icon, label, title, lede, align = "left", children }) {
|
||||
export default function PageHero({
|
||||
trail = [],
|
||||
icon: Icon,
|
||||
label,
|
||||
title,
|
||||
lede,
|
||||
align = "left",
|
||||
children,
|
||||
isEn: isEnProp,
|
||||
locale: localeProp,
|
||||
}) {
|
||||
const center = align === "center";
|
||||
const isEn =
|
||||
isEnProp !== undefined
|
||||
? isEnProp
|
||||
: localeProp
|
||||
? localeProp === "en"
|
||||
: trail.some((t) => t.isEn || (t.href && t.href.startsWith("/en")));
|
||||
|
||||
return (
|
||||
<section className="shell pt-8 sm:pt-12">
|
||||
{trail.length > 0 && (
|
||||
<nav aria-label="Trilha de navegação" className="flex flex-wrap items-center gap-2 text-sm text-muted">
|
||||
<Link href="/" className="inline-flex min-h-11 min-w-11 items-center justify-center transition-colors hover:text-accent">
|
||||
Início
|
||||
<nav aria-label={isEn ? "Breadcrumb navigation" : "Trilha de navegação"} className="flex flex-wrap items-center gap-2 text-sm text-muted">
|
||||
<Link href={isEn ? "/en" : "/"} className="inline-flex min-h-11 min-w-11 items-center justify-center transition-colors hover:text-accent">
|
||||
{isEn ? "Home" : "Início"}
|
||||
</Link>
|
||||
{trail.map((item, i) => (
|
||||
<span key={item.label} className="flex min-h-11 items-center gap-2">
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
* diagrama nunca divergem: corrigir um pino no JSON corrige os dois.
|
||||
*/
|
||||
|
||||
const GRUPOS = [
|
||||
const GRUPOS_PT = [
|
||||
{
|
||||
id: "entrada",
|
||||
titulo: "Somente entrada",
|
||||
@@ -26,7 +26,7 @@ const GRUPOS = [
|
||||
cor: "text-accent",
|
||||
explicacao:
|
||||
"Aceitam apenas leitura. Não podem ser configurados como saída e não possuem resistores de pull-up ou pull-down internos. Se precisar de um, coloque no circuito.",
|
||||
combina: (avisos) => /apenas de entrada|input only/.test(avisos),
|
||||
combina: (avisos) => /apenas de entrada|input only/i.test(avisos),
|
||||
},
|
||||
{
|
||||
id: "flash",
|
||||
@@ -36,8 +36,8 @@ const GRUPOS = [
|
||||
explicacao:
|
||||
"Já estão conectados à memória de onde o firmware é lido. Usá-los como GPIO comum normalmente trava o chip ou corrompe a execução. Em módulos com flash interna eles nem chegam ao encapsulamento.",
|
||||
combina: (avisos) =>
|
||||
/(flash|psram)/.test(avisos) &&
|
||||
/(dedicad|utilizado pela mem|não deve ser utilizado|não é recomendado)/.test(avisos),
|
||||
/(flash|psram)/i.test(avisos) &&
|
||||
/(dedicad|utilizado pela mem|não deve ser utilizado|não é recomendado|connected to|dedicated to|should not be used|not recommended)/i.test(avisos),
|
||||
},
|
||||
{
|
||||
id: "strapping",
|
||||
@@ -48,7 +48,7 @@ const GRUPOS = [
|
||||
"O chip lê o nível destes pinos no instante do reset para decidir como inicializar. Dá para usá-los depois do boot, mas o circuito externo não pode forçar o nível errado durante o reset, senão a placa não inicia ou entra em modo de gravação sozinha.",
|
||||
combina: (avisos, cats) =>
|
||||
cats.includes("Strapping") ||
|
||||
/strapping|modo de boot|modo de inicialização/.test(avisos),
|
||||
/strapping|modo de boot|modo de inicialização|boot mode/i.test(avisos),
|
||||
},
|
||||
{
|
||||
id: "debug",
|
||||
@@ -57,7 +57,7 @@ const GRUPOS = [
|
||||
cor: "text-accent",
|
||||
explicacao:
|
||||
"São a UART de gravação e as linhas de JTAG. Continuam utilizáveis como GPIO, mas ao reaproveitá-los você perde o caminho de gravar e depurar a placa sem desconectar o que estiver ali.",
|
||||
combina: (avisos, cats) => /debugging/.test(avisos) || cats.includes("JTAG"),
|
||||
combina: (avisos, cats) => /debugging|gravação/i.test(avisos) || cats.includes("JTAG"),
|
||||
},
|
||||
{
|
||||
id: "usb",
|
||||
@@ -66,7 +66,7 @@ const GRUPOS = [
|
||||
cor: "text-accent",
|
||||
explicacao:
|
||||
"Saem de fábrica ligados ao USB Serial/JTAG interno. Para usá-los como GPIO é preciso desativar essa função, o que também remove a gravação por USB direto.",
|
||||
combina: (avisos) => /usb serial\/jtag|usb_d[+-]/.test(avisos),
|
||||
combina: (avisos) => /usb serial\/jtag|usb_d[+-]/i.test(avisos),
|
||||
},
|
||||
{
|
||||
id: "eletrico",
|
||||
@@ -75,7 +75,68 @@ const GRUPOS = [
|
||||
cor: "text-gold",
|
||||
explicacao:
|
||||
"Precisam de nível definido por hardware: pull-up externo ou circuito RC de atraso. Deixá-los soltos causa reset aleatório ou inicialização instável.",
|
||||
combina: (avisos) => /flutuando/.test(avisos),
|
||||
combina: (avisos) => /flutuando|floating/i.test(avisos),
|
||||
},
|
||||
];
|
||||
|
||||
const GRUPOS_EN = [
|
||||
{
|
||||
id: "entrada",
|
||||
titulo: "Input only",
|
||||
icone: ArrowDownToLine,
|
||||
cor: "text-accent",
|
||||
explicacao:
|
||||
"Input only pins. They cannot be configured as outputs and do not have internal pull-up or pull-down resistors. If needed, add them to your external circuit.",
|
||||
combina: (avisos) => /apenas de entrada|input only/i.test(avisos),
|
||||
},
|
||||
{
|
||||
id: "flash",
|
||||
titulo: "Connected to flash/PSRAM memory",
|
||||
icone: HardDrive,
|
||||
cor: "text-copper",
|
||||
explicacao:
|
||||
"Already connected to the memory where firmware is stored and executed. Using them as general-purpose GPIO typically crashes the chip or corrupts execution. In modules with internal flash, they are not brought out to the package pins.",
|
||||
combina: (avisos) =>
|
||||
/(flash|psram)/i.test(avisos) &&
|
||||
/(dedicad|utilizado pela mem|não deve ser utilizado|não é recomendado|connected to|dedicated to|should not be used|not recommended)/i.test(avisos),
|
||||
},
|
||||
{
|
||||
id: "strapping",
|
||||
titulo: "Strapping pins (boot mode)",
|
||||
icone: Power,
|
||||
cor: "text-gold",
|
||||
explicacao:
|
||||
"The chip samples the logic level of these pins during reset to determine the boot mode. You can use them after booting, but external circuitry must not force the wrong level during reset, or the board will fail to boot or enter download mode unexpectedly.",
|
||||
combina: (avisos, cats) =>
|
||||
cats.includes("Strapping") ||
|
||||
/strapping|modo de boot|modo de inicialização|boot mode/i.test(avisos),
|
||||
},
|
||||
{
|
||||
id: "debug",
|
||||
titulo: "Flashing and debugging",
|
||||
icone: Bug,
|
||||
cor: "text-accent",
|
||||
explicacao:
|
||||
"These are the flashing UART and JTAG lines. They can still be used as GPIO, but reusing them removes the ability to flash and debug the board without disconnecting connected peripherals.",
|
||||
combina: (avisos, cats) => /debugging|gravação/i.test(avisos) || cats.includes("JTAG"),
|
||||
},
|
||||
{
|
||||
id: "usb",
|
||||
titulo: "Native USB",
|
||||
icone: Usb,
|
||||
cor: "text-accent",
|
||||
explicacao:
|
||||
"Connected by default to the internal USB Serial/JTAG controller. Using them as GPIO requires disabling this peripheral, which also removes direct USB flashing.",
|
||||
combina: (avisos) => /usb serial\/jtag|usb_d[+-]/i.test(avisos),
|
||||
},
|
||||
{
|
||||
id: "eletrico",
|
||||
titulo: "Must not float",
|
||||
icone: Zap,
|
||||
cor: "text-gold",
|
||||
explicacao:
|
||||
"Require a defined hardware logic level: external pull-up or RC delay circuit. Leaving them floating causes random resets or unstable boot behavior.",
|
||||
combina: (avisos) => /flutuando|floating/i.test(avisos),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -85,8 +146,9 @@ function rotuloDoPino(pino) {
|
||||
return gpio && gpio !== pino.nome ? `${pino.nome} · ${gpio}` : pino.nome;
|
||||
}
|
||||
|
||||
function derivarGrupos(conexoes) {
|
||||
return GRUPOS.map((grupo) => {
|
||||
function derivarGrupos(conexoes, isEn) {
|
||||
const listaGrupos = isEn ? GRUPOS_EN : GRUPOS_PT;
|
||||
return listaGrupos.map((grupo) => {
|
||||
const vistos = new Map();
|
||||
for (const pino of conexoes) {
|
||||
if (!["io", "analog", "dedicated"].includes(pino.tipo)) continue;
|
||||
@@ -101,10 +163,10 @@ function derivarGrupos(conexoes) {
|
||||
}).filter((g) => g.pinos.length > 0);
|
||||
}
|
||||
|
||||
export default function PinRestrictions({ conexoes, serieKey }) {
|
||||
export default function PinRestrictions({ conexoes, serieKey, isEn = false }) {
|
||||
if (!conexoes?.length) return null;
|
||||
|
||||
const grupos = derivarGrupos(conexoes);
|
||||
const grupos = derivarGrupos(conexoes, isEn);
|
||||
if (!grupos.length) return null;
|
||||
|
||||
const totalPinos = new Set(grupos.flatMap((g) => g.pinos)).size;
|
||||
@@ -115,13 +177,21 @@ export default function PinRestrictions({ conexoes, serieKey }) {
|
||||
<span className="grid h-9 w-9 place-items-center rounded-full bg-gold-soft text-gold">
|
||||
<AlertTriangle className="h-4 w-4" aria-hidden="true" />
|
||||
</span>
|
||||
Pinos com restrição de uso
|
||||
{isEn ? "Pins with usage restrictions" : "Pinos com restrição de uso"}
|
||||
</h2>
|
||||
|
||||
<p className="mt-3 max-w-3xl text-sm leading-relaxed text-muted">
|
||||
Nem todo pino do {serieKey} está livre para uso geral. {totalPinos} deles têm alguma
|
||||
condição: já estão ocupados por memória, são lidos durante o boot ou só funcionam
|
||||
como entrada. Vale conferir antes de fechar o esquemático.
|
||||
{isEn ? (
|
||||
<>
|
||||
Not every pin on the {serieKey} is free for general-purpose use. {totalPinos} of them have conditions: occupied by memory, sampled during boot, or function as input only. Check before finalizing your schematic.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Nem todo pino do {serieKey} está livre para uso geral. {totalPinos} deles têm alguma
|
||||
condição: já estão ocupados por memória, são lidos durante o boot ou só funcionam
|
||||
como entrada. Vale conferir antes de fechar o esquemático.
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
|
||||
<div className="mt-6 grid gap-4 md:grid-cols-2">
|
||||
@@ -131,7 +201,7 @@ export default function PinRestrictions({ conexoes, serieKey }) {
|
||||
<Icone className={`h-4 w-4 shrink-0 ${corIcone}`} aria-hidden="true" />
|
||||
<h3 className="text-sm font-semibold text-ink">{titulo}</h3>
|
||||
<span className="ml-auto text-xs text-muted tabular-nums">
|
||||
{pinos.length} {pinos.length === 1 ? "pino" : "pinos"}
|
||||
{pinos.length} {pinos.length === 1 ? (isEn ? "pin" : "pino") : (isEn ? "pins" : "pinos")}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -150,11 +220,14 @@ export default function PinRestrictions({ conexoes, serieKey }) {
|
||||
|
||||
<div className="mt-6 flex flex-col justify-between gap-4 border-t border-line pt-5 sm:flex-row sm:items-center">
|
||||
<p className="max-w-xl text-sm leading-relaxed text-muted">
|
||||
Estes grupos vêm dos mesmos dados do diagrama de conexões. Lá você vê pino a pino
|
||||
todas as funções, o domínio de alimentação e os avisos completos.
|
||||
{isEn ? (
|
||||
"These groups are derived from the same data as the pinout diagram. There you can see every pin's full functions, power domain, and complete engineering notes."
|
||||
) : (
|
||||
"Estes grupos vêm dos mesmos dados do diagrama de conexões. Lá você vê pino a pino todas as funções, o domínio de alimentação e os avisos completos."
|
||||
)}
|
||||
</p>
|
||||
<Link href="#connections" className="btn btn-ghost shrink-0">
|
||||
Abrir diagrama de pinos
|
||||
{isEn ? "Open pinout diagram" : "Abrir diagrama de pinos"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
+52
-27
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useState, useEffect, useRef, useMemo, useCallback } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useRouter, usePathname } from "next/navigation";
|
||||
import {
|
||||
Search,
|
||||
X,
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
import { preparar, buscar, EXEMPLOS_DE_BUSCA } from "@/lib/searchEngine";
|
||||
import { normalizar } from "@/lib/searchTopics";
|
||||
|
||||
const TIPOS = {
|
||||
const TIPOS_PT = {
|
||||
resposta: { label: "Resposta", Icon: Sparkles, cor: "bg-accent text-accent-contrast" },
|
||||
pino: { label: "Pinos", Icon: Plug, cor: "bg-accent text-accent-contrast" },
|
||||
pagina: { label: "Página", Icon: FileText, cor: "bg-surface-2 text-ink-soft" },
|
||||
@@ -32,11 +32,23 @@ const TIPOS = {
|
||||
componente: { label: "Componente", Icon: Box, cor: "bg-surface-2 text-ink-soft" },
|
||||
};
|
||||
|
||||
const TIPOS_EN = {
|
||||
resposta: { label: "Answer", Icon: Sparkles, cor: "bg-accent text-accent-contrast" },
|
||||
pino: { label: "Pins", Icon: Plug, cor: "bg-accent text-accent-contrast" },
|
||||
pagina: { label: "Page", Icon: FileText, cor: "bg-surface-2 text-ink-soft" },
|
||||
serie: { label: "Series", Icon: Cpu, cor: "bg-accent-soft text-accent" },
|
||||
framework: { label: "Framework", Icon: Terminal, cor: "bg-teal-soft text-teal" },
|
||||
glossario: { label: "Glossary", Icon: BookOpen, cor: "bg-copper-soft text-copper" },
|
||||
erro: { label: "Error", Icon: AlertTriangle, cor: "bg-gold-soft text-gold" },
|
||||
componente: { label: "Component", Icon: Box, cor: "bg-surface-2 text-ink-soft" },
|
||||
};
|
||||
|
||||
const INTELIGENTES = new Set(["resposta", "pino"]);
|
||||
|
||||
const EXEMPLOS_EN = ["flash s3", "usb pins c6", "gpio0 esp32", "brownout", "LVGL", "FreeRTOS"];
|
||||
|
||||
function Destaque({ texto, termos }) {
|
||||
if (!termos.length) return texto;
|
||||
// Posições do texto normalizado só valem para o original se o comprimento não mudou.
|
||||
const norm = normalizar(texto);
|
||||
if (norm.length !== texto.length) return texto;
|
||||
const marcas = new Array(texto.length).fill(false);
|
||||
@@ -85,6 +97,13 @@ function Pilula({ children, onClick, forte = false }) {
|
||||
}
|
||||
|
||||
export default function SearchDialog() {
|
||||
const pathname = usePathname() || "";
|
||||
const locale = pathname === "/en" || pathname.startsWith("/en/") ? "en" : "pt";
|
||||
const isEn = locale === "en";
|
||||
|
||||
const TIPOS = isEn ? TIPOS_EN : TIPOS_PT;
|
||||
const EXEMPLOS = isEn ? EXEMPLOS_EN : EXEMPLOS_DE_BUSCA;
|
||||
|
||||
const [aberto, setAberto] = useState(false);
|
||||
const [montado, setMontado] = useState(false);
|
||||
const [consulta, setConsulta] = useState("");
|
||||
@@ -124,9 +143,16 @@ export default function SearchDialog() {
|
||||
const carregarIndice = useCallback(() => {
|
||||
setErro(false);
|
||||
let cancelado = false;
|
||||
fetch("/api/busca?v=2", { cache: "no-cache" })
|
||||
const url = isEn ? "/api/busca/en?v=2" : "/api/busca?v=2";
|
||||
fetch(url, { cache: "no-cache" })
|
||||
.then((r) => {
|
||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
||||
if (!r.ok) {
|
||||
// Fallback para /api/busca caso a rota dinâmica do locale falhe
|
||||
return fetch("/api/busca?v=2", { cache: "no-cache" }).then((r2) => {
|
||||
if (!r2.ok) throw new Error(`HTTP ${r2.status}`);
|
||||
return r2.json();
|
||||
});
|
||||
}
|
||||
return r.json();
|
||||
})
|
||||
.then((dados) => {
|
||||
@@ -141,7 +167,7 @@ export default function SearchDialog() {
|
||||
return () => {
|
||||
cancelado = true;
|
||||
};
|
||||
}, []);
|
||||
}, [isEn]);
|
||||
|
||||
// Carrega o índice (textos + especificações + pinos) na primeira abertura.
|
||||
useEffect(() => {
|
||||
@@ -182,7 +208,6 @@ export default function SearchDialog() {
|
||||
if (!item) return;
|
||||
fechar();
|
||||
router.push(item.href);
|
||||
// Se já estamos na página de destino, só a âncora muda: avisa quem escuta (abas da série).
|
||||
if (item.href.includes("#")) setTimeout(() => window.dispatchEvent(new HashChangeEvent("hashchange")), 80);
|
||||
}
|
||||
|
||||
@@ -213,17 +238,17 @@ export default function SearchDialog() {
|
||||
id="botao-busca"
|
||||
onClick={() => setAberto(true)}
|
||||
className="flex h-11 min-w-11 shrink-0 cursor-pointer items-center justify-center gap-2 rounded-full border border-line px-3 text-ink transition-colors hover:bg-surface-2 xl:px-4"
|
||||
aria-label="Buscar no ESPDocs (Ctrl+K)"
|
||||
aria-label={isEn ? "Search ESPDocs (Ctrl+K)" : "Buscar no ESPDocs (Ctrl+K)"}
|
||||
>
|
||||
<Search className="h-4 w-4" aria-hidden="true" />
|
||||
<span className="hidden text-sm font-medium xl:inline">Buscar</span>
|
||||
<span className="hidden text-sm font-medium xl:inline">{isEn ? "Search" : "Buscar"}</span>
|
||||
<kbd className="hidden rounded-md border border-line bg-surface-2 px-1.5 py-0.5 font-mono text-xs font-semibold text-muted xl:inline">Ctrl K</kbd>
|
||||
</button>
|
||||
|
||||
{montado &&
|
||||
aberto &&
|
||||
createPortal(
|
||||
<div className="fixed inset-0 z-[120] flex items-start justify-center px-4 pt-[8vh]" role="dialog" aria-modal="true" aria-label="Buscar no ESPDocs">
|
||||
<div className="fixed inset-0 z-[120] flex items-start justify-center px-4 pt-[8vh]" role="dialog" aria-modal="true" aria-label={isEn ? "Search ESPDocs" : "Buscar no ESPDocs"}>
|
||||
<div className="dialog-scrim absolute inset-0 bg-black/45 backdrop-blur-sm" onClick={fechar} />
|
||||
<div className="dialog-panel relative flex max-h-[80vh] w-full max-w-2xl flex-col overflow-hidden rounded-3xl border border-line bg-canvas shadow-2xl">
|
||||
<div className="flex items-center gap-3 border-b border-line px-5">
|
||||
@@ -235,17 +260,17 @@ export default function SearchDialog() {
|
||||
value={consulta}
|
||||
onChange={(e) => setConsulta(e.target.value)}
|
||||
onKeyDown={onInputKey}
|
||||
placeholder="Pergunte ao ESPDocs: “flash s3”, “pinos usb c6”, “gpio0 esp32”…"
|
||||
placeholder={isEn ? "Ask ESPDocs: “flash s3”, “usb pins c6”, “gpio0 esp32”…" : "Pergunte ao ESPDocs: “flash s3”, “pinos usb c6”, “gpio0 esp32”…"}
|
||||
className="flex-1 bg-transparent py-5 text-base text-ink outline-none placeholder:text-muted"
|
||||
autoComplete="off"
|
||||
spellCheck={false}
|
||||
aria-label="Termo de busca"
|
||||
aria-label={isEn ? "Search query" : "Termo de busca"}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={fechar}
|
||||
className="grid h-9 w-9 cursor-pointer place-items-center rounded-full text-muted transition-colors hover:bg-surface-2 hover:text-ink"
|
||||
aria-label="Fechar busca"
|
||||
aria-label={isEn ? "Close search" : "Fechar busca"}
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
@@ -253,7 +278,7 @@ export default function SearchDialog() {
|
||||
|
||||
{entendeu && (
|
||||
<div className="flex flex-wrap items-center gap-2 border-b border-line bg-surface px-5 py-2.5">
|
||||
<span className="text-xs font-semibold text-muted">Entendi:</span>
|
||||
<span className="text-xs font-semibold text-muted">{isEn ? "Understood:" : "Entendi:"}</span>
|
||||
{interpretacao.chips.map((c) => (
|
||||
<Pilula key={c.chave} forte>{c.nome}</Pilula>
|
||||
))}
|
||||
@@ -265,7 +290,7 @@ export default function SearchDialog() {
|
||||
|
||||
{sugestoes.length > 0 && (
|
||||
<div className="flex flex-wrap items-center gap-2 border-b border-line px-5 py-2.5">
|
||||
<span className="text-xs font-semibold text-muted">{interpretacao.chips.length ? "Perguntar sobre:" : "Para qual chip?"}</span>
|
||||
<span className="text-xs font-semibold text-muted">{interpretacao.chips.length ? (isEn ? "Ask about:" : "Perguntar sobre:") : (isEn ? "Which chip?" : "Para qual chip?")}</span>
|
||||
{sugestoes.map((s) => (
|
||||
<Pilula key={s.rotulo} onClick={() => anexar(s.anexar)}>
|
||||
{s.rotulo}
|
||||
@@ -277,36 +302,36 @@ export default function SearchDialog() {
|
||||
<div ref={listaRef} className="flex-1 overflow-y-auto p-2" role="listbox">
|
||||
{erro && (
|
||||
<div className="p-6 text-center">
|
||||
<p className="text-sm font-semibold text-danger">Não foi possível carregar o índice de busca.</p>
|
||||
<p className="text-sm font-semibold text-danger">{isEn ? "Could not load search index." : "Não foi possível carregar o índice de busca."}</p>
|
||||
<button
|
||||
type="button"
|
||||
onClick={carregarIndice}
|
||||
className="btn btn-primary btn-sm mt-3"
|
||||
>
|
||||
Tentar novamente
|
||||
{isEn ? "Try again" : "Tentar novamente"}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{!erro && !indice && <p className="p-6 text-center text-sm text-muted">Carregando…</p>}
|
||||
{!erro && !indice && <p className="p-6 text-center text-sm text-muted">{isEn ? "Loading…" : "Carregando…"}</p>}
|
||||
|
||||
{indice && vazia && (
|
||||
<div className="px-3 pb-3 pt-1">
|
||||
<p className="text-xs font-semibold text-muted">Experimente perguntar</p>
|
||||
<p className="text-xs font-semibold text-muted">{isEn ? "Try asking" : "Experimente perguntar"}</p>
|
||||
<div className="mt-2 flex flex-wrap gap-2">
|
||||
{EXEMPLOS_DE_BUSCA.map((ex) => (
|
||||
{EXEMPLOS.map((ex) => (
|
||||
<Pilula key={ex} onClick={() => setConsulta(ex)}>
|
||||
{ex}
|
||||
</Pilula>
|
||||
))}
|
||||
</div>
|
||||
<p className="mt-4 text-xs font-semibold text-muted">Ir para</p>
|
||||
<p className="mt-4 text-xs font-semibold text-muted">{isEn ? "Go to" : "Ir para"}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{indice && !vazia && resultados.length === 0 && (
|
||||
<div className="p-8 text-center">
|
||||
<p className="font-display text-lg font-semibold text-ink">Nenhum resultado para “{consulta}”</p>
|
||||
<p className="mt-1 text-sm text-muted">Tente “brownout”, “flash s3”, “pinos usb c6” ou “LVGL”.</p>
|
||||
<p className="font-display text-lg font-semibold text-ink">{isEn ? `No results for “${consulta}”` : `Nenhum resultado para “${consulta}”`}</p>
|
||||
<p className="mt-1 text-sm text-muted">{isEn ? "Try “brownout”, “flash s3”, “usb pins c6” or “LVGL”." : "Tente “brownout”, “flash s3”, “pinos usb c6” ou “LVGL”."}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -369,10 +394,10 @@ export default function SearchDialog() {
|
||||
</div>
|
||||
|
||||
<div className="hidden items-center gap-4 border-t border-line bg-surface px-4 py-2.5 text-xs text-muted md:flex">
|
||||
<span className="flex items-center gap-1"><ArrowUp className="h-3 w-3" /><ArrowDown className="h-3 w-3" /> navegar</span>
|
||||
<span className="flex items-center gap-1"><CornerDownLeft className="h-3 w-3" /> abrir</span>
|
||||
<span><kbd className="font-mono font-semibold">Esc</kbd> fechar</span>
|
||||
<span className="ml-auto">{vazia ? "Dica: pressione / em qualquer página" : `${resultados.length} resultado(s)`}</span>
|
||||
<span className="flex items-center gap-1"><ArrowUp className="h-3 w-3" /><ArrowDown className="h-3 w-3" /> {isEn ? "navigate" : "navegar"}</span>
|
||||
<span className="flex items-center gap-1"><CornerDownLeft className="h-3 w-3" /> {isEn ? "open" : "abrir"}</span>
|
||||
<span><kbd className="font-mono font-semibold">Esc</kbd> {isEn ? "close" : "fechar"}</span>
|
||||
<span className="ml-auto">{vazia ? (isEn ? "Tip: press / on any page" : "Dica: pressione / em qualquer página") : `${resultados.length} ${isEn ? "result(s)" : "resultado(s)"}`}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
export default function SeriesTabMenu({ tabs }) {
|
||||
export default function SeriesTabMenu({ tabs, isEn = false }) {
|
||||
const availableTabs = tabs.filter((tab) => tab.available);
|
||||
const [activeTab, setActiveTab] = useState(availableTabs[0]?.id);
|
||||
const refs = useRef({});
|
||||
@@ -59,7 +59,7 @@ export default function SeriesTabMenu({ tabs }) {
|
||||
|
||||
return (
|
||||
<div id="diagrama-abas" className="scroll-mt-28">
|
||||
<div role="tablist" aria-label="Placa e diagrama" className="no-scrollbar flex gap-2 overflow-x-auto pb-1">
|
||||
<div role="tablist" aria-label={isEn ? "Board and diagram" : "Placa e diagrama"} className="no-scrollbar flex gap-2 overflow-x-auto pb-1">
|
||||
{availableTabs.map((tab, indice) => (
|
||||
<button
|
||||
key={tab.id}
|
||||
|
||||
@@ -0,0 +1,422 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "ANT",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"RF antenna connection (Wi-Fi and Bluetooth)"
|
||||
],
|
||||
"categorias": [
|
||||
"Antenna",
|
||||
"RF"
|
||||
],
|
||||
"avisos": [
|
||||
"Dedicated RF pin. Avoid long traces without 50-ohm impedance matching."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDDA3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog power supply de 3.3V"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended voltage: 3.3V (3.0V to 3.6V)",
|
||||
"Powers analog and RF circuits of the chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDDA3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog power supply de 3.3V"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended voltage: 3.3V (3.0V to 3.6V)",
|
||||
"Powers analog and RF circuits of the chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "GPIO0",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Analog input pin ADC1 Channel 0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "GPIO1",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"ADC1_CH1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Analog input pin ADC1 Channel 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "GPIO2",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO2",
|
||||
"ADC1_CH2",
|
||||
"FSPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Mapped to SPI MISO (FSPIQ) by default during flash initialization"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "CHIP_EN",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Enable chip (Power-up / Reset)"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Active High. Pull high to enable chip boot.",
|
||||
"Do not leave this pin floating. Use an external RC delay circuit for stable boot."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "GPIO3",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"ADC1_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Analog input pin ADC1 Channel 3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "GPIO4",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"MTMS",
|
||||
"FSPIQ",
|
||||
"ADC1_CH4"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"SPI",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Multifunction pin: JTAG MTMS, SPI2 MISO, and ADC1 Channel 4.",
|
||||
"Can be used for JTAG debugging together with other JTAG pins."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "GPIO5",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"MTDI",
|
||||
"FSPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Multifunction pin: JTAG MTDI and SPI2 Write Protect (FSPIWP)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "VDD3P3_RTC",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"RTC domain and low-power I/O power supply"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended voltage: 3.3V"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "GPIO6",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"MTCK",
|
||||
"FSPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Multifunction pin: JTAG MTCK and SPI2 Clock (FSPICLK)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "GPIO7",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO7",
|
||||
"MTDO",
|
||||
"FSPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Multifunction pin: JTAG MTDO and SPI2 MOSI (FSPID)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO8"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Strapping pin for boot control.",
|
||||
"Together with GPIO9, selects SoC boot mode (must be high/1 during reset for Joint Download Boot if GPIO9=0)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO9"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Primary Strapping pin. High level (1) at reset activates SPI Boot (default via weak pull-up).",
|
||||
"Low level (0) at reset puts chip into UART/SPI download mode."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"FSPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Multifunction pin: SPI2 Chip Select 0 (FSPICS0)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "VDD3P3_CPU",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Digital power supply da CPU e IOs correspondentes (3.3V)"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended voltage: 3.3V"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "GPIO18",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO18"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "GPIO19",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO19",
|
||||
"U0RXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"UART0 receive pin (Serial RX by default for flashing and monitoring)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "GPIO20",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"U0TXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"UART0 transmit pin (Serial TX by default for flashing and monitoring)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"3.3V analog input power supply"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"External crystal oscillator connection (Output)"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"External crystal oscillator connection (Input)"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"3.3V analog input power supply"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GND",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Center ground pad (Exposed Pad)"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Must be properly soldered to the PCB ground plane (GND) for stable performance and thermal dissipation."
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,643 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "LNA_IN",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"RF signals input/output (Wi-Fi and Bluetooth) to antenna"
|
||||
],
|
||||
"categorias": [
|
||||
"Antenna"
|
||||
],
|
||||
"avisos": [
|
||||
"Refer to datasheet section 2.4 for more details on analog pins"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "XTAL_32K_P",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"XTAL_32K_P",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "XTAL_32K_N",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"XTAL_32K_N",
|
||||
"ADC1_CH1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "GPIO2",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO2",
|
||||
"ADC1_CH2",
|
||||
"FSPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"This pin does not set boot mode, but connecting it with a pull-up is recommended to prevent glitches (see datasheet section 3.1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "CHIP_EN",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Enable chip"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Pulling this pin high enables chip operation",
|
||||
"Pulling this pin low disables chip operation",
|
||||
"Do not leave this pin floating, use an external pull-up resistor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "GPIO3",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"ADC1_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "MTMS",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"ADC1_CH4",
|
||||
"FSPIHD",
|
||||
"MTMS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "MTDI",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"ADC2_CH0",
|
||||
"FSPIWP",
|
||||
"MTDI"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "VDD3P3_RTC",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Low-power domain and partial digital domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "MTCK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"FSPICLK",
|
||||
"MTCK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "MTDO",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO7",
|
||||
"FSPID",
|
||||
"MTDO"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO8"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"Used to control chip boot mode (see datasheet section 3.1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO9"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used to control chip boot mode (see datasheet section 3.1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"FSPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "VDD3P3_CPU",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Digital domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "VDD_SPI",
|
||||
"tipo": "power",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"Internal/external flash power supply input/output",
|
||||
"GPIO11"
|
||||
],
|
||||
"categorias": [
|
||||
"Power",
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details",
|
||||
"Can only be used as GPIO if flash memory is powered by an external supply"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "SPIHD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"SPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "SPIWP",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"SPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "SPICS0",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO14",
|
||||
"SPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "SPICLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO15",
|
||||
"SPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "SPID",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO16",
|
||||
"SPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "SPIQ",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"SPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GPIO18",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO18",
|
||||
"USB_D-"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"By default, this pin is used for USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "GPIO19",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO19",
|
||||
"USB_D+"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"By default, this pin is used for USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "U0RXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"U0RXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "U0TXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO21",
|
||||
"U0TXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will have internal pull-up enabled",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Negative clock input/output"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"See datasheet section 2.3.2 for analog pin details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Positive clock input/output"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"See datasheet section 2.3.2 for analog pin details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": [
|
||||
"Circuit electrical ground reference (GND)"
|
||||
],
|
||||
"categorias": [
|
||||
"GND"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,944 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "VDDA6",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": [
|
||||
"Circuit electrical ground reference (GND)"
|
||||
],
|
||||
"categorias": [
|
||||
"GND"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDDA7",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Negative clock input/output"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"See datasheet section 2.3.3 for analog pin details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Positive clock input/output"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"See datasheet section 2.3.3 for analog pin details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "VDDA8",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "CHIP_PU",
|
||||
"tipo": "analog",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"Enable chip"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Pulling this pin high enables chip operation",
|
||||
"Pulling this pin low disables chip operation",
|
||||
"Do not leave this pin floating, use an external pull-up resistor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Low-power digital domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "XTAL_32K_P",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"LP_GDIO0",
|
||||
"XTAL_32K_P",
|
||||
"LP_UART_DTRN"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"Clock",
|
||||
"UART"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "XTAL_32K_N",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"LP_GDIO1",
|
||||
"XTAL_32K_N",
|
||||
"LP_UART_DSRN",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"Clock",
|
||||
"UART",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "MTMS",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO2",
|
||||
"LP_GDIO2",
|
||||
"LP_UART_RTSN",
|
||||
"LP_I2C_SDA",
|
||||
"ADC1_CH1",
|
||||
"FSPIQ",
|
||||
"MTMS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"I2C",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"I2C_SDA function is available in low-power (LP) mode",
|
||||
"Pin used for debugging",
|
||||
"Used to control crystal oscillator frequency (see datasheet section 3.5)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "MTDI",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"LP_GDIO3",
|
||||
"LP_UART_CTSN",
|
||||
"LP_I2C_SCL",
|
||||
"ADC1_CH2",
|
||||
"MTDI"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"I2C",
|
||||
"ADC",
|
||||
"JTAG",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"I2C_SDA function is available in low-power (LP) mode",
|
||||
"Pin used for debugging",
|
||||
"Used to control SDIO Slave timing (see datasheet section 3.2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "MTCK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"LP_GDIO4",
|
||||
"LP_UART_RXD",
|
||||
"ADC1_CH3",
|
||||
"FSPIHD",
|
||||
"MTCK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "MTDO",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"LP_GDIO5",
|
||||
"LP_UART_TXD",
|
||||
"ADC1_CH4",
|
||||
"FSPIWP",
|
||||
"MTDO"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO6",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"LP_GDIO6",
|
||||
"ADC1_CH5",
|
||||
"FSPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO7",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO7",
|
||||
"FSPID",
|
||||
"SDIO_DATA1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"Used to control JTAG signal source (see datasheet section 3.4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO8",
|
||||
"SDIO_DATA0",
|
||||
"PAD_COMP0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO9",
|
||||
"SDIO_CLK",
|
||||
"PAD_COMP1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"FSPICS0",
|
||||
"SDIO_CMD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "U0TXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO11",
|
||||
"U0TXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will have internal pull-up enabled",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "U0RXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"U0RXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "GPIO13",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"USB_D-",
|
||||
"SDIO_DATA3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input",
|
||||
"By default, this pin is used for USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "GPIO14",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO14",
|
||||
"USB_D+",
|
||||
"SDIO_DATA4"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal USB pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal USB pull-up enabled",
|
||||
"By default, this pin is used for USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "VDDPST2",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"High-performance digital domain and partial analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "SPICS1",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO15",
|
||||
"SPICS1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "SPICS0",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO16",
|
||||
"SPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "SPIQ",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"SPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "SPIWP",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO18",
|
||||
"SPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "VDD_SPI",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Power output for external flash",
|
||||
"GPIO19"
|
||||
],
|
||||
"categorias": [
|
||||
"Power",
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details",
|
||||
"Can only be used as GPIO if external flash memory is powered by an external supply"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "SPIHD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"SPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "SPICLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO21",
|
||||
"SPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "SPID",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO22",
|
||||
"SPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "GPIO23",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST3"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO23"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "34",
|
||||
"nome": "GPIO24",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST3"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO24"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "35",
|
||||
"nome": "GPIO25",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST3"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO25"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"Used to control SDIO Slave timing (see datasheet section 3.4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "36",
|
||||
"nome": "GPIO26",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST3"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO26"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"Used to control chip boot mode (see datasheet section 3.1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "37",
|
||||
"nome": "GPIO27",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST3"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO27"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used to control chip boot mode (see datasheet section 3.1)",
|
||||
"Used to control UART0 ROM message printing (see datasheet section 3.3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "38",
|
||||
"nome": "GPIO28",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST3"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO28"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used to control chip boot mode (see datasheet section 3.1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "39",
|
||||
"nome": "VDDPST3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"High-performance digital domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "40",
|
||||
"nome": "VDDA1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "41",
|
||||
"nome": "VDDA2",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "42",
|
||||
"nome": "ANT_2G",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"RF antenna connection for 2 GHz band"
|
||||
],
|
||||
"categorias": [
|
||||
"Antenna"
|
||||
],
|
||||
"avisos": [
|
||||
"Refer to datasheet section 2.4 for more details on analog pins"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "43",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": [
|
||||
"Circuit electrical ground reference (GND)"
|
||||
],
|
||||
"categorias": [
|
||||
"GND"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "44",
|
||||
"nome": "VDDA3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "44",
|
||||
"nome": "VDDA4",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "45",
|
||||
"nome": "VDDA5",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "47",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": [
|
||||
"Circuit electrical ground reference (GND)"
|
||||
],
|
||||
"categorias": [
|
||||
"GND"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "48",
|
||||
"nome": "ANT_5G",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"RF antenna connection for 5 GHz band"
|
||||
],
|
||||
"categorias": [
|
||||
"Antenna"
|
||||
],
|
||||
"avisos": [
|
||||
"Refer to datasheet section 2.4 for more details on analog pins"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,841 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "ANT",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"RF antenna connection"
|
||||
],
|
||||
"categorias": [
|
||||
"Antenna"
|
||||
],
|
||||
"avisos": [
|
||||
"Refer to datasheet section 2.4 for more details on analog pins"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDDA3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDDA3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "CHIP_PU",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Enable chip"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Pulling this pin high enables chip operation",
|
||||
"Pulling this pin low disables chip operation",
|
||||
"Do not leave this pin floating, use an external pull-up resistor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Low-power digital domain and partial analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "XTAL_32K_P",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"LP_GDIO0",
|
||||
"XTAL_32K_P",
|
||||
"LP_UART_DTRN",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"Clock",
|
||||
"UART"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "XTAL_32K_N",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"LP_GDIO1",
|
||||
"XTAL_32K_N",
|
||||
"LP_UART_DSRN",
|
||||
"ADC1_CH1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"Clock",
|
||||
"UART",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "GPIO2",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO2",
|
||||
"LP_GDIO2",
|
||||
"LP_UART_RTSN",
|
||||
"ADC1_CH2",
|
||||
"FSPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"ADC",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "GPIO3",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"LP_GDIO3",
|
||||
"LP_UART_CTSN",
|
||||
"ADC1_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "MTMS",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"LP_GDIO4",
|
||||
"LP_UART_RXD",
|
||||
"ADC1_CH3",
|
||||
"FSPIHD",
|
||||
"MTMS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"Pin used for debugging",
|
||||
"Used to control SDIO Slave timing (see datasheet section 3.2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "MTDI",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"LP_GDIO5",
|
||||
"LP_UART_TXD",
|
||||
"ADC1_CH5",
|
||||
"FSPIWP",
|
||||
"MTDI"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"Pin used for debugging",
|
||||
"Used to control SDIO Slave timing (see datasheet section 3.2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "MTCK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"LP_GDIO6",
|
||||
"LP_I2C_SDA",
|
||||
"ADC1_CH6",
|
||||
"FSPICLK",
|
||||
"MTCK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"I2C",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"I2C_SDA function is available in low-power (LP) mode",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "MTDO",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO7",
|
||||
"LP_GDIO7",
|
||||
"LP_I2C_SCL",
|
||||
"FSPID",
|
||||
"MTDO"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"I2C",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input",
|
||||
"I2C_SDA function is available in low-power (LP) mode",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO8"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"Used to control chip boot mode (see datasheet section 3.1)",
|
||||
"Used to control UART0 ROM message printing (see datasheet section 3.3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO9"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used to control chip boot mode (see datasheet section 3.1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO10"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "GPIO11",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO11"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "GPIO12",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"USB_D-"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input",
|
||||
"By default, this pin is used for USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "GPIO13",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"USB_D+"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"By default, this pin is used for USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "SPICS0",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO24",
|
||||
"SPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "SPIQ",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO25",
|
||||
"SPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "SPIWP",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO26",
|
||||
"SPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "VDD_SPI",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Power supply input/output for flash memory",
|
||||
"GPIO27"
|
||||
],
|
||||
"categorias": [
|
||||
"Power",
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details",
|
||||
"Can only be used as GPIO if external flash memory is powered by an external supply"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "SPIHD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO28",
|
||||
"SPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "SPICLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO29",
|
||||
"SPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "SPID",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO30",
|
||||
"SPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used by SPI flash memory",
|
||||
"Not recommended to use this pin as GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "GPIO15",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO15"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"Used to control JTAG signal source (see datasheet section 3.4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "VDDA2",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"High-performance digital domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "U0TXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO16",
|
||||
"U0TXD",
|
||||
"FSPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will have internal pull-up enabled",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "U0RXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"U0RXD",
|
||||
"FSPICS1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "SDIO_CMD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO18",
|
||||
"SDIO_CMD",
|
||||
"FSPICS2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "SDIO_CLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO19",
|
||||
"SDIO_CLK",
|
||||
"FSPICS3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "SDIO_DATA0",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"SDIO_DATA0",
|
||||
"FSPICS4"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "34",
|
||||
"nome": "SDIO_DATA1",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO21",
|
||||
"SDIO_DATA1",
|
||||
"FSPICS5"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "35",
|
||||
"nome": "SDIO_DATA2",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO22",
|
||||
"SDIO_DATA2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "36",
|
||||
"nome": "SDIO_DATA3",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO23",
|
||||
"SDIO_DATA3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will have internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "37",
|
||||
"nome": "VDDA1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "38",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Negative clock input/output"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"Refer to datasheet section 2.4 for more details on analog pins"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "39",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Positive clock input/output"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"Refer to datasheet section 2.4 for more details on analog pins"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "40",
|
||||
"nome": "VDDA2",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "41",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": [
|
||||
"Circuit electrical ground reference (GND)"
|
||||
],
|
||||
"categorias": [
|
||||
"GND"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,729 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "ANT_2G",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"RF antenna connection (Wi-Fi and Bluetooth)"
|
||||
],
|
||||
"categorias": [
|
||||
"Antenna",
|
||||
"RF"
|
||||
],
|
||||
"avisos": [
|
||||
"Dedicated 2.4 GHz RF pin. Requires 50-ohm impedance matching."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDDA3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"3.3V analog domain power supply"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended voltage: 3.3V (3.0V to 3.6V). Supplies power to RF and clock circuits."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDDA4",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"3.3V analog domain power supply"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended voltage: 3.3V (3.0V to 3.6V). Supplies power to RF and clock circuits."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "CHIP_PU",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Enable chip (Power-up / Reset)"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Active High. Pull high to enable chip boot.",
|
||||
"Do not leave this pin floating. An external RC circuit is recommended for clean reset."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Digital power supply for HP (High Performance) and LP (Low Power) domains"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended voltage: 3.3V. Powers low-power digital circuitry and associated pins."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "GPIO0",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"XTAL_32K_P"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"Low-power multifunction pin. Can connect to external 32 kHz crystal (Input P)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "GPIO1",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"XTAL_32K_N",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Multifunction pin. External 32 kHz crystal connection (Output N) and ADC1 Channel 0 analog input."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "GPIO2",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "GPIO3",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"MTMS",
|
||||
"ADC1_CH1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"ADC",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Multifunction pin: JTAG MTMS, ADC1 Channel 1, and Strapping pin for SDIO clock edge control.",
|
||||
"Floating by default during reset."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "GPIO4",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"MTDI",
|
||||
"ADC1_CH2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"ADC",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Multifunction pin: JTAG MTDI, ADC1 Channel 2, and Strapping pin for SDIO clock edge control.",
|
||||
"Floating by default during reset."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "GPIO5",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"MTCK",
|
||||
"ADC1_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Multifunction pin: JTAG MTCK and ADC1 Channel 3 analog input."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "GPIO6",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"MTDO"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Multifunction pin: JTAG MTDO."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "GPIO25",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO25",
|
||||
"SDIO_CMD",
|
||||
"FSPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"High-speed multifunction pin: SDIO Command or SPI2 Chip Select 0."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO26",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO26",
|
||||
"SDIO_CLK",
|
||||
"FSPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"High-speed multifunction pin: SDIO Clock or SPI2 Clock."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO27",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO27",
|
||||
"SDIO_DATA0",
|
||||
"FSPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"High-speed multifunction pin: SDIO Data 0 or SPI2 MOSI (FSPID)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO28",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO28",
|
||||
"SDIO_DATA1",
|
||||
"FSPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"High-speed pin: SDIO Data 1 or SPI2 MISO (FSPIQ)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "GPIO22",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO22",
|
||||
"SDIO_DATA2",
|
||||
"FSPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"High-speed pin: SDIO Data 2 or SPI2 Write Protect."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "GPIO23",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO23",
|
||||
"SDIO_DATA3",
|
||||
"FSPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"High-speed pin: SDIO Data 3 or SPI2 Hold."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "GPIO14",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO14",
|
||||
"SPICS1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Dedicated Chip Select 1 pin for SPI Flash/PSRAM memory interface."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "GPIO15",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO15",
|
||||
"SPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Dedicated Chip Select 0 pin for SPI Flash memory interface."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "VDDPST2",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"HP (High Performance) digital domain power supply"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended voltage: 3.3V (3.0V to 3.6V). Powers high-speed digital interfaces."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "GPIO16",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO16",
|
||||
"SPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Data Q (MISO) pin for SPI flash memory interface."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "GPIO17",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"SPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Write Protect pin for SPI flash memory interface."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "VDD_SPI",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"LDO output voltage generated from VDDPST2 to power Flash and PSRAM"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Software-configurable output voltage matching internal/external flash specs (typically 3.3V or 1.8V).",
|
||||
"Must not be used as a general high-current power source."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GPIO19",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO19",
|
||||
"SPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Hold control pin for SPI flash memory interface."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "GPIO20",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"SPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Clock signal pin for SPI flash memory interface."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "GPIO21",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO21",
|
||||
"SPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Data D (MOSI) pin for SPI flash memory interface."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "GPIO12",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"USB_D-"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Negative signal pin of integrated USB Serial/JTAG transceiver."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "GPIO13",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"USB_D+"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Positive signal pin of integrated USB Serial/JTAG transceiver.",
|
||||
"Equipped with integrated pull-up enabled by default during USB initialization."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "GPIO24",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO24"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO8"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Strapping pin for boot mode selection and ROM log printing control.",
|
||||
"Floating by default during reset. High level (1) enables boot log printing."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO9"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Primary Strapping pin for boot mode selection.",
|
||||
"Equipped with integrated weak pull-up. High level (1) at reset enables SPI Boot (loads from flash). Low level (0) forces Download mode."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"U0RXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"UART0 serial reception (Serial RX for firmware flashing and debugging)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "34",
|
||||
"nome": "GPIO11",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO11",
|
||||
"U0TXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"UART0 serial transmission (Serial TX for external firmware flashing and debugging)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "35",
|
||||
"nome": "GPIO29",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO29"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "36",
|
||||
"nome": "GPIO7",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO7"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Strapping pin for JTAG signal source selection (early boot).",
|
||||
"No internal pull resistors at reset. Must be kept stable by external circuitry if used."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "37",
|
||||
"nome": "VDDA1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"3.3V analog domain power supply"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "38",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"External 40 MHz crystal oscillator connection (Output N)"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "39",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"External 40 MHz crystal oscillator connection (Input P)"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "40",
|
||||
"nome": "VDDA2",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"3.3V analog domain power supply"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "41",
|
||||
"nome": "GND",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Center ground pad (Exposed Pad)"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Must be properly soldered to the PCB ground plane (GND) for stable RF and thermal performance."
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,603 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "GPIO0",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"FSPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "GPIO1",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"FSPICS0",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "MTMS",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"FSPIWP",
|
||||
"ADC1_CH1",
|
||||
"MTMS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"ADC",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "MTDO",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"FSPIHD",
|
||||
"ADC1_CH2",
|
||||
"MTDO"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"ADC",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "MTCK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"FSPICLK",
|
||||
"ADC1_CH3",
|
||||
"MTCK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"ADC",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "MTDI",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"FSPID",
|
||||
"ADC1_CH4",
|
||||
"MTDI"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"ADC",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"I/O domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO8"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"Used to control chip boot mode (see datasheet section 3.1)",
|
||||
"Used to control UART0 ROM message printing (see datasheet section 3.3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO9"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Used to control chip boot mode (see datasheet section 3.1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"ZCD0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "GPIO11",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO11",
|
||||
"ZCD1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO12",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDA_PMU",
|
||||
"VBAT"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO12"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "XTAL_32K_P",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDA_PMU",
|
||||
"VBAT"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"XTAL_32K_P"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "XTAL_32K_N",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDA_PMU",
|
||||
"VBAT"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO14",
|
||||
"XTAL_32K_N"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "CHIP_EN",
|
||||
"tipo": "analog",
|
||||
"alimentacao": [
|
||||
"VBAT"
|
||||
],
|
||||
"funcoes": [
|
||||
"Enable chip"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Pulling this pin high enables chip operation",
|
||||
"Pulling this pin low disables chip operation",
|
||||
"Do not leave this pin floating, use an external pull-up resistor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "VBAT",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain or battery power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "VDDA_PMU",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"I/O domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "GPIO22",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO22"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "U0RXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO23",
|
||||
"U0RXD",
|
||||
"FSPICS1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "U0TXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO24",
|
||||
"U0TXD",
|
||||
"FSPICS2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input with internal pull-up enabled",
|
||||
"Pin used for debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "GPIO25",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO24",
|
||||
"FSPICS3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"During reset, this pin will be configured as input",
|
||||
"After reset, this pin will be configured as input",
|
||||
"Used to control JTAG signal source (see datasheet section 3.3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GPIO26",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO26",
|
||||
"FSPICS4",
|
||||
"USB_D-"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input",
|
||||
"By default, this pin is used for USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "GPIO27",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO27",
|
||||
"FSPICS5",
|
||||
"USB_D+"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"After reset, this pin will be configured as input with internal USB pull-up enabled",
|
||||
"By default, this pin is used for USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Negative clock input/output"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"See datasheet section 2.3.2 for analog pin details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Positive clock input/output"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"See datasheet section 2.3.2 for analog pin details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Analog domain power supply input"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Recommended Voltage: 3.3V",
|
||||
"Minimum Recommended Voltage: 3.0V",
|
||||
"Maximum Recommended Voltage: 3.6V",
|
||||
"See datasheet section 2.5 for chip power supply details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "ANT",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"RF antenna connection"
|
||||
],
|
||||
"categorias": [
|
||||
"Antenna"
|
||||
],
|
||||
"avisos": [
|
||||
"Refer to datasheet section 2.4 for more details on analog pins"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": [
|
||||
"Circuit electrical ground reference (GND)"
|
||||
],
|
||||
"categorias": [
|
||||
"GND"
|
||||
]
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,391 @@
|
||||
{
|
||||
"ESP-IDF": {
|
||||
"nome": "ESP-IDF",
|
||||
"icone": "⚙️",
|
||||
"nome_completo": "Espressif IoT Development Framework",
|
||||
"descricao": "Official native Espressif framework for all ESP32 SoCs. Based on multicore FreeRTOS and CMake, providing full control over silicon, peripherals, radio, and modular component architecture.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Official Base Framework",
|
||||
"funcao_principal": "Industrial and high-performance development with direct register access, real-time RTOS, and complete protocol stack",
|
||||
"caracteristicas": [
|
||||
"Real-time operating system (FreeRTOS SMP multicore)",
|
||||
"Native support for ESP Component Registry via idf_component.yml",
|
||||
"Full connectivity stack for Wi-Fi 4/6, BLE 5.x, Zigbee and Thread",
|
||||
"Support for all SoCs (ESP32, S2, S3, C2, C3, C6, H2, P4)",
|
||||
"Advanced power management and Deep Sleep modes",
|
||||
"Robust security: Secure Boot v2, Flash Encryption and Hardware Crypto",
|
||||
"Encrypted OTA updates with automatic rollback",
|
||||
"Modern Clang/GCC toolchain, C++23 support and JTAG OpenOCD debugging"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Commercial and industrial IoT products",
|
||||
"Devices with strict battery and low-power requirements",
|
||||
"Real-time applications with precise interrupt control",
|
||||
"Security systems with hardware encryption",
|
||||
"High-performance multiprotocol gateways"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-idf.c",
|
||||
"exemplos": "https://github.com/espressif/esp-idf/tree/master/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-idf/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-idf",
|
||||
"cor": "#E74C3C"
|
||||
},
|
||||
"ESP-RainMaker": {
|
||||
"nome": "ESP-RainMaker",
|
||||
"icone": "☁️",
|
||||
"nome_completo": "ESP RainMaker AIoT Cloud Platform",
|
||||
"descricao": "Complete cloud and firmware platform from Espressif for connected products. Build IoT devices without developing backend or mobile apps from scratch.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Cloud & AIoT Framework",
|
||||
"funcao_principal": "Accelerated smart product development with mobile apps (iOS/Android), AWS Serverless cloud and voice control (Alexa/Google Home)",
|
||||
"caracteristicas": [
|
||||
"Assisted Wi-Fi and BLE provisioning via official mobile app",
|
||||
"Dynamic UI generation in app based on firmware parameters",
|
||||
"Native integration with Alexa and Google Assistant",
|
||||
"Simultaneous local control (via mDNS/HTTP) and cloud control",
|
||||
"RainMaker Dashboard for fleet management and OTA",
|
||||
"Native compatibility with Matter nodes and device Bridges",
|
||||
"Integrated library via ESP Component Registry (espressif/esp_rainmaker)"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Smart appliances and consumer lighting",
|
||||
"IoT products with tight time-to-market constraints",
|
||||
"Devices requiring mobile app control without custom backend costs",
|
||||
"Remote monitoring systems with centralized OTA"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-rainmaker.c",
|
||||
"exemplos": "https://github.com/espressif/esp-rainmaker/tree/master/examples",
|
||||
"documentacao": "https://rainmaker.espressif.com/docs/",
|
||||
"repositorio": "https://github.com/espressif/esp-rainmaker",
|
||||
"cor": "#3B82F6"
|
||||
},
|
||||
"ESP-Matter": {
|
||||
"nome": "ESP-Matter",
|
||||
"icone": "🏠",
|
||||
"nome_completo": "ESP Matter SDK",
|
||||
"descricao": "Official Espressif SDK for the Matter smart home standard (formerly Project CHIP). Enables interoperability across Apple HomeKit, Google Home, Alexa, and Home Assistant.",
|
||||
"linguagem": "C++",
|
||||
"tipo": "Smart Home Framework",
|
||||
"funcao_principal": "Development of smart devices and bridges compliant with the unified Matter standard over Wi-Fi and Thread",
|
||||
"caracteristicas": [
|
||||
"Full implementation of Matter specification clusters",
|
||||
"Transport support over Wi-Fi and Thread (802.15.4 on ESP32-H2 and ESP32-C6)",
|
||||
"Simplified commissioning via BLE or On-Network",
|
||||
"Simultaneous compatibility with Apple Home, Google Home, Alexa and SmartThings",
|
||||
"Security based on Device Attestation Certificates (DAC)",
|
||||
"Matter Bridge support (bridging legacy Zigbee/BLE devices into Matter)",
|
||||
"Direct integration with ESP-IDF and ESP Component Registry"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Interoperable smart bulbs, plugs, switches and dimmers",
|
||||
"Presence, temperature, humidity and contact sensors",
|
||||
"Electronic locks and window blind actuators",
|
||||
"Residential Matter Border Routers and Bridges"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-matter.c",
|
||||
"exemplos": "https://github.com/espressif/esp-matter/tree/main/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-matter/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-matter",
|
||||
"cor": "#F59E0B"
|
||||
},
|
||||
"ESP-ADF": {
|
||||
"nome": "ESP-ADF",
|
||||
"icone": "🎵",
|
||||
"nome_completo": "ESP Audio Development Framework",
|
||||
"descricao": "Specialized framework for high-quality digital audio processing, streaming, and playback on ESP32 SoCs.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Audio & Voice Framework",
|
||||
"funcao_principal": "Creation of flexible audio pipelines with decoders, network streaming, equalization and acoustic effects",
|
||||
"caracteristicas": [
|
||||
"Modular audio pipeline architecture (Audio Elements & Audio Stream)",
|
||||
"Multi-codec support: MP3, AAC, FLAC, WAV, OGG, Opus and AMR",
|
||||
"Audio streaming over HTTP, HTTPS, HLS, RTSP and WebSockets",
|
||||
"Bluetooth A2DP (Sink/Source) and Bluetooth Handsfree (HFP) support",
|
||||
"Acoustic processing algorithms (AEC, AGC, NS, parametric equalizers)",
|
||||
"Support for dedicated audio boards such as ESP32-LyraT and ESP32-S3-Korvo"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Smart speakers and internet radio receivers",
|
||||
"Intercoms, walkie-talkies and VoIP systems",
|
||||
"Music playback players with PSRAM",
|
||||
"Building automation background audio systems"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-adf.c",
|
||||
"exemplos": "https://github.com/espressif/esp-adf/tree/master/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-adf/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-adf",
|
||||
"cor": "#0284C7"
|
||||
},
|
||||
"ESP-SR": {
|
||||
"nome": "ESP-SR",
|
||||
"icone": "🎙️",
|
||||
"nome_completo": "ESP Speech Recognition Framework",
|
||||
"descricao": "Local speech recognition and edge AI audio processing framework, enabling offline voice commands without internet connection.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Voice & AI Framework",
|
||||
"funcao_principal": "Offline voice control with wake word detection, localized command speech-to-intent and acoustic front-end (AFE)",
|
||||
"caracteristicas": [
|
||||
"WakeNet: high-accuracy wake word engine (e.g., 'Hi ESP', 'Alexa')",
|
||||
"MultiNet: offline speech command recognition for multiple languages",
|
||||
"Acoustic Front-End (AFE): noise suppression, beamforming and echo cancellation (AEC)",
|
||||
"Hardware acceleration on ESP32-S3 via Xtensa vector instructions",
|
||||
"Zero cloud latency and complete user voice privacy"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Offline voice-controlled home appliances",
|
||||
"Industrial voice terminals in noisy environments",
|
||||
"Privacy-focused smart home gadgets",
|
||||
"Interactive toys and hands-free assistive devices"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-sr.c",
|
||||
"exemplos": "https://github.com/espressif/esp-sr/tree/master/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-sr/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-sr",
|
||||
"cor": "#6366F1"
|
||||
},
|
||||
"ESP-IoT-Solution": {
|
||||
"nome": "ESP-IoT-Solution",
|
||||
"icone": "🧩",
|
||||
"nome_completo": "ESP-IoT-Solution Driver & Peripheral Suite",
|
||||
"descricao": "Collection of drivers, peripheral libraries and hardware solutions for ESP32 and ESP-IDF.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Peripheral Library & Drivers",
|
||||
"funcao_principal": "Modular peripheral drivers for displays, touch, sensors, audio DACs and power management",
|
||||
"caracteristicas": [
|
||||
"Drivers for OLED, TFT, e-Paper displays and LED matrices",
|
||||
"Support for environmental, motion and power sensors",
|
||||
"Touch sensing algorithms and gesture recognition",
|
||||
"USB host and device class implementations",
|
||||
"Modular integration via ESP Component Registry"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Smart screens and HMI interfaces",
|
||||
"Sensor hubs and data loggers",
|
||||
"Battery-powered portable gadgets",
|
||||
"Custom peripheral prototyping"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-iot-solution.c",
|
||||
"exemplos": "https://github.com/espressif/esp-iot-solution/tree/master/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-iot-solution/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-iot-solution",
|
||||
"cor": "#10B981"
|
||||
},
|
||||
"ESP-NOW": {
|
||||
"nome": "ESP-NOW & Mesh",
|
||||
"icone": "📡",
|
||||
"nome_completo": "ESP-NOW Protocol & Mesh-Lite",
|
||||
"descricao": "Connectionless, ultra-fast wireless protocol developed by Espressif for short-packet peer-to-peer communication.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Network Protocol & Mesh",
|
||||
"funcao_principal": "Ultra-low-latency, low-overhead communication between ESP devices without a Wi-Fi router",
|
||||
"caracteristicas": [
|
||||
"Fast peer-to-peer communication without Wi-Fi association",
|
||||
"Sub-millisecond packet latency",
|
||||
"Low energy consumption, ideal for battery sensors",
|
||||
"Payload up to 250 bytes with optional AES-128 encryption",
|
||||
"Supports one-to-many and many-to-one topologies"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Remote controls and wireless buttons",
|
||||
"Battery-powered sensor nodes",
|
||||
"Low-latency smart home triggers",
|
||||
"Industrial point-to-point telemetry"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-now.c",
|
||||
"exemplos": "https://github.com/espressif/esp-now/tree/master/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html",
|
||||
"repositorio": "https://github.com/espressif/esp-now",
|
||||
"cor": "#8B5CF6"
|
||||
},
|
||||
"ESP-Zigbee-SDK": {
|
||||
"nome": "ESP-Zigbee-SDK",
|
||||
"icone": "🐝",
|
||||
"nome_completo": "ESP Zigbee SDK (ZCL & ZBOSS)",
|
||||
"descricao": "Official Zigbee 3.0 SDK for IEEE 802.15.4-capable ESP32 SoCs (ESP32-H2 and ESP32-C6).",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Smart Home & Mesh",
|
||||
"funcao_principal": "Building standard Zigbee 3.0 devices including Coordinators, Routers and End Devices",
|
||||
"caracteristicas": [
|
||||
"Certified Zigbee 3.0 protocol stack (ZCL, BDB)",
|
||||
"Support for Zigbee Coordinator, Router and Sleepy End Device roles",
|
||||
"Native IEEE 802.15.4 hardware radio on ESP32-H2 and ESP32-C6",
|
||||
"Interoperable with commercial Zigbee ecosystems (Philips Hue, Tuya, Zigbee2MQTT)",
|
||||
"OTA cluster support for Zigbee firmware updates"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Zigbee home automation sensors and actuators",
|
||||
"Zigbee to Wi-Fi/Ethernet gateway hubs",
|
||||
"Low-power sleepy sensor nodes",
|
||||
"Commercial lighting networks"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-zigbee.c",
|
||||
"exemplos": "https://github.com/espressif/esp-zigbee-sdk/tree/main/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-zigbee-sdk/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-zigbee-sdk",
|
||||
"cor": "#EC4899"
|
||||
},
|
||||
"ESP-WHO": {
|
||||
"nome": "ESP-WHO",
|
||||
"icone": "📷",
|
||||
"nome_completo": "ESP Image Processing & Vision Framework",
|
||||
"descricao": "Computer vision and image recognition framework designed for ESP32-S3 and ESP32-CAM devices.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Computer Vision & AI",
|
||||
"funcao_principal": "Face detection, face recognition, human presence and cat/dog detection on microcontrollers",
|
||||
"caracteristicas": [
|
||||
"Optimized neural networks for Xtensa LX7 and vector instructions",
|
||||
"Face detection and recognition pipelines",
|
||||
"Support for DVP and MIPI-CSI camera sensors (OV2640, OV3660, OV5640)",
|
||||
"Works with PSRAM for image buffering and tensor storage",
|
||||
"Real-time processing directly on device"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Smart video doorbells and access control",
|
||||
"Human presence detection for energy saving",
|
||||
"Edge camera monitoring systems",
|
||||
"Vision-guided robotics"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-who.c",
|
||||
"exemplos": "https://github.com/espressif/esp-who/tree/master/examples",
|
||||
"documentacao": "https://github.com/espressif/esp-who",
|
||||
"repositorio": "https://github.com/espressif/esp-who",
|
||||
"cor": "#F97316"
|
||||
},
|
||||
"ESP-NN": {
|
||||
"nome": "ESP-NN",
|
||||
"icone": "🧠",
|
||||
"nome_completo": "ESP Neural Network Acceleration Library",
|
||||
"descricao": "Neural network acceleration library optimized specifically for ESP32 architectures.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Specialized AI Library",
|
||||
"funcao_principal": "Hardware-accelerated kernel execution for machine learning inference at the edge (TinyML)",
|
||||
"caracteristicas": [
|
||||
"Official accelerator backend for TensorFlow Lite for Microcontrollers (TFLM)",
|
||||
"Efficient 8-bit and 16-bit quantization to minimize RAM and Flash usage",
|
||||
"SIMD vector instructions acceleration on ESP32-S3 and ESP32-P4",
|
||||
"Zero RTOS overhead for critical inference kernels",
|
||||
"Fully open source and maintainable"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Audio classification and vibration analysis (predictive maintenance)",
|
||||
"Anomaly detection on industrial sensor streams",
|
||||
"IMU gesture recognition",
|
||||
"Ultralight vision models on microcontrollers"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-nn.c",
|
||||
"exemplos": "https://github.com/espressif/esp-nn/tree/master/test_app",
|
||||
"documentacao": "https://github.com/espressif/esp-nn",
|
||||
"repositorio": "https://github.com/espressif/esp-nn",
|
||||
"cor": "#14B8A6"
|
||||
},
|
||||
"ESP-DSP": {
|
||||
"nome": "ESP-DSP",
|
||||
"icone": "📊",
|
||||
"nome_completo": "ESP Digital Signal Processing Library",
|
||||
"descricao": "Official digital signal processing library for the ESP32 family, providing hardware-accelerated math routines.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Specialized Signal Processing Library",
|
||||
"funcao_principal": "High-speed execution of intensive mathematical algorithms including FFT, matrix operations and digital filtering",
|
||||
"caracteristicas": [
|
||||
"Fast Fourier Transforms (Real and Complex FFT) optimized in Assembly",
|
||||
"Digital filters (IIR, FIR) and Kalman filter estimators",
|
||||
"Matrix, vector and dot product operations",
|
||||
"Floating-point and fixed-point support (Radix-2 and Radix-4)",
|
||||
"Custom optimizations for Xtensa Dual-Core and RISC-V architectures"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Real-time audio and vibration spectral analysis",
|
||||
"Noise reduction filters for biomedical and industrial sensors",
|
||||
"High-precision motor control and FOC algorithms",
|
||||
"Edge data compression and encoding"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-dsp.c",
|
||||
"exemplos": "https://github.com/espressif/esp-dsp/tree/master/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-dsp/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-dsp",
|
||||
"cor": "#A855F7"
|
||||
},
|
||||
"Rust-ESP": {
|
||||
"nome": "Rust on ESP32",
|
||||
"icone": "🦀",
|
||||
"nome_completo": "ESP-RS Rust Ecosystem for ESP32",
|
||||
"descricao": "Modern Rust language development ecosystem for the ESP32 family, combining memory safety, robust concurrency, and high performance.",
|
||||
"linguagem": "Rust",
|
||||
"tipo": "Modern Language & Framework",
|
||||
"funcao_principal": "Safe, high-performance firmware development in both bare-metal mode (no_std via esp-hal) and full stack (std via esp-idf-svc)",
|
||||
"caracteristicas": [
|
||||
"Bare-metal no_std mode with esp-hal: full control without RTOS and ultra-fast boot",
|
||||
"Standard std mode with esp-idf-svc: access to Rust standard library, Wi-Fi, BLE, HTTP, MQTT and threads",
|
||||
"Compile-time prevention against memory corruption and data races",
|
||||
"Target support for Xtensa (ESP32, S2, S3) and native RISC-V (C2, C3, C6, H2, P4)",
|
||||
"Integration with embedded-hal ecosystem and async/await via embassy",
|
||||
"Official tooling: espflash for flashing and serial monitoring, esp-generate for project templates"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Mission-critical systems where memory safety errors are unacceptable",
|
||||
"Modern IoT applications with clean asynchronous concurrency",
|
||||
"Industrial devices requiring high reliability and security",
|
||||
"Modern robotics and instrumentation projects"
|
||||
],
|
||||
"exemplo": "/exemplos/rust-esp.rs",
|
||||
"exemplos": "https://github.com/esp-rs/esp-hal/tree/main/examples",
|
||||
"documentacao": "https://esp-rs.github.io/book/",
|
||||
"repositorio": "https://github.com/esp-rs",
|
||||
"cor": "#E44D26"
|
||||
},
|
||||
"Arduino": {
|
||||
"nome": "Arduino Core",
|
||||
"icone": "🛠️",
|
||||
"nome_completo": "Arduino Core for ESP32",
|
||||
"descricao": "Official Arduino core implementation running on top of ESP-IDF (v3.x+ based on ESP-IDF v5.1+), combining maximum ease of use with ESP32 advanced features.",
|
||||
"linguagem": "C++",
|
||||
"tipo": "Popular Alternative Framework",
|
||||
"funcao_principal": "Rapid prototyping, education and fast development leveraging the vast Arduino library ecosystem",
|
||||
"caracteristicas": [
|
||||
"Classic setup() and loop() syntax with hundreds of thousands of compatible libraries",
|
||||
"Runs as a FreeRTOS task on top of official ESP-IDF",
|
||||
"Full support for Wi-Fi, Bluetooth Classic/BLE, WebServer and WebSockets",
|
||||
"Compatible with Arduino IDE 2.x, PlatformIO and VS Code",
|
||||
"Updated support for all popular SoCs (ESP32, S2, S3, C3, C6)",
|
||||
"Direct access to underlying ESP-IDF APIs when needed"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Rapid prototyping and proof-of-concept (PoC) validation",
|
||||
"Educational, maker and academic projects",
|
||||
"Simple IoT systems with dashboards (Blynk, Adafruit IO, ThingSpeak)",
|
||||
"DIY home automation and hobbyist robotics"
|
||||
],
|
||||
"exemplo": "/exemplos/arduino.ino",
|
||||
"exemplos": "https://github.com/espressif/arduino-esp32/tree/master/docs/en/tutorials",
|
||||
"documentacao": "https://docs.espressif.com/projects/arduino-esp32/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/arduino-esp32",
|
||||
"cor": "#00979D"
|
||||
},
|
||||
"MicroPython": {
|
||||
"nome": "MicroPython",
|
||||
"icone": "🐍",
|
||||
"nome_completo": "MicroPython for ESP32",
|
||||
"descricao": "Lean and efficient implementation of Python 3 optimized to run directly on ESP32 microcontrollers with a real-time interpreter.",
|
||||
"linguagem": "Python",
|
||||
"tipo": "Language & Dynamic Interpreter",
|
||||
"funcao_principal": "Interactive development and rapid Python prototyping with an interactive REPL console and direct hardware control",
|
||||
"caracteristicas": [
|
||||
"Full Python 3 interpreter compiling directly to RAM bytecode",
|
||||
"Interactive REPL console over serial and WebREPL over Wi-Fi",
|
||||
"Built-in filesystem (LittleFS / FAT) with .py script uploads without recompilation",
|
||||
"Native modules: machine, network, bluetooth, espnow and asyncio",
|
||||
"Ideal for teaching physical computing and embedded algorithms on real hardware"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Teaching physical computing and university laboratory courses",
|
||||
"Rapid prototyping and fast sensor testing on the workbench",
|
||||
"Automated hardware test bench scripts",
|
||||
"Experimental IoT data collection applications"
|
||||
],
|
||||
"exemplo": "/exemplos/micropython.py",
|
||||
"exemplos": "https://github.com/micropython/micropython/tree/master/examples",
|
||||
"documentacao": "https://docs.micropython.org/en/latest/esp32/",
|
||||
"repositorio": "https://github.com/micropython/micropython",
|
||||
"cor": "#2B2B2B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,732 @@
|
||||
{
|
||||
"ESP32": {
|
||||
"nome_completo": "ESP32 (Classic)",
|
||||
"icone": "🔷",
|
||||
"descricao": "The original model with dual-core processor and wide range of peripherals",
|
||||
"arquitetura": "Xtensa® LX6 dual-core 32-bit",
|
||||
"nucleos": "1 (Single-core) or 2 (Dual-core)",
|
||||
"frequencia": "Up to 240 MHz",
|
||||
"coprocessador_ulp": "Yes",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/192/256",
|
||||
"sha": "SHA-1/256/384/512",
|
||||
"rsa": "Yes (RSA/MPI up to 4096 bits)",
|
||||
"ecc": "No",
|
||||
"ecdsa": "No",
|
||||
"hmac": "No",
|
||||
"assinatura_digital": "No",
|
||||
"key_manager": "No",
|
||||
"rng": "Yes (hardware TRNG)",
|
||||
"criptografia_flash": "Yes (AES-256, legacy scheme)",
|
||||
"secure_boot": "V1 (AES, legacy); V2 (RSA-3072, RSA-PSS) starting from rev v3.0 (ECO3)",
|
||||
"protecao_dpa": "No"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, up to 150 Mbps)",
|
||||
"bluetooth": "Bluetooth 4.2 BR/EDR (Classic) and Bluetooth LE (dual mode)",
|
||||
"ethernet": "Yes (Integrated Ethernet MAC)",
|
||||
"memoria_sram": "520 KB",
|
||||
"memoria_sram_rtc": "16 KB (divided into RTC FAST and RTC SLOW)",
|
||||
"memoria_rom": "448 KB (for boot and core functions)",
|
||||
"flash_externa": "Up to 16 MB via QSPI",
|
||||
"psram_externa": "Up to 8 MB via QSPI (in specific modules such as WROVER)",
|
||||
"gpio": "34",
|
||||
"adc": "2x 12-bit SAR ADC, up to 18 channels",
|
||||
"dac": "2x 8-bit DAC",
|
||||
"touch": "10 capacitive channels",
|
||||
"uart": "3",
|
||||
"spi": "4 (SPI, HSPI, VSPI - 2 can be used for Flash/PSRAM)",
|
||||
"i2c": "2",
|
||||
"i2s": "2",
|
||||
"pwm": "LED PWM (up to 16 channels), Motor PWM",
|
||||
"ethernet_mac": "1 (requires external PHY)",
|
||||
"can": "1 (CAN 2.0, TWAI®)",
|
||||
"sdio": "1 (SD/SDIO/MMC Host), 1 (SDIO/SPI Slave)",
|
||||
"sensor_hall": "1 (internal)",
|
||||
"sensor_temperatura": "No (removed from datasheet in 2018; no driver in ESP-IDF)",
|
||||
"consumo_energia": {
|
||||
"active_cpu_240mhz": "30-68 mA",
|
||||
"active_wifi_tx": "180-240 mA",
|
||||
"modem_sleep": "20-44 mA",
|
||||
"light_sleep": "0.8 mA",
|
||||
"deep_sleep": "10-150 µA",
|
||||
"hibernation": "5 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C to 125°C",
|
||||
"temperatura_armazenamento": "-40°C to 150°C",
|
||||
"depuracao": "External JTAG (requires probe, e.g. ESP-PROG)",
|
||||
"esp_idf_minimo": "Since initial release (v3.x and earlier)",
|
||||
"arduino_core": "Yes (147 board definitions in official core)",
|
||||
"encapsulamento": "QFN48 (6×6 mm) and QFN48 (5×5 mm)",
|
||||
"modulos": "ESP32-MINI-1, ESP32-PICO-MINI-02, ESP32-PICO-V3, ESP32-PICO-V3-02 and 11 more",
|
||||
"datasheet": "https://documentation.espressif.com/esp32_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html",
|
||||
"placa": "/placas/esp32.png",
|
||||
"cor": "#007bff"
|
||||
},
|
||||
"ESP32-S2": {
|
||||
"nome_completo": "ESP32-S2",
|
||||
"icone": "🔒",
|
||||
"descricao": "Focused on security and low power, with native USB and the only ADC with 13-bit output",
|
||||
"arquitetura": "Xtensa® LX7 single-core 32-bit",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Up to 240 MHz",
|
||||
"coprocessador_ulp": "Yes (RISC-V)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/192/256 with GCM",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Yes (RSA/MPI up to 4096 bits)",
|
||||
"ecc": "No",
|
||||
"ecdsa": "No",
|
||||
"hmac": "Yes",
|
||||
"assinatura_digital": "Yes",
|
||||
"key_manager": "No",
|
||||
"rng": "Yes (hardware TRNG)",
|
||||
"criptografia_flash": "XTS-AES-128/256",
|
||||
"secure_boot": "V2 (RSA-3072)",
|
||||
"protecao_dpa": "No"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, up to 150 Mbps)",
|
||||
"bluetooth": "No",
|
||||
"memoria_sram": "320 KB",
|
||||
"memoria_sram_rtc": "16 KB",
|
||||
"memoria_rom": "128 KB",
|
||||
"flash_externa": "Up to 1 GB via QSPI",
|
||||
"psram_externa": "Up to 1 GB via QSPI/Octal SPI",
|
||||
"gpio": "43",
|
||||
"adc": "2x SAR ADC, up to 20 channels: 13-bit output (0–8191, unique in family), 12-bit effective resolution starting from rev v1.0 (errata ADC-112)",
|
||||
"dac": "2x 8-bit DAC",
|
||||
"touch": "14 capacitive channels",
|
||||
"uart": "2",
|
||||
"spi": "4 (SPI0/1 for Flash, SPI2/3 for general use)",
|
||||
"i2c": "2",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (up to 8 channels)",
|
||||
"usb": "1 (USB OTG 1.1 Full-Speed)",
|
||||
"lcd": "8/16-bit LCD interface",
|
||||
"camera": "8/16-bit DVP interface",
|
||||
"sensor_temperatura": "1 (internal)",
|
||||
"consumo_energia": {
|
||||
"active_wifi_tx": "160-310 mA",
|
||||
"modem_sleep_cpu_160mhz": "14-24 mA",
|
||||
"light_sleep": "750 µA",
|
||||
"deep_sleep": "20-190 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C to 105°C",
|
||||
"temperatura_armazenamento": "-40°C to 150°C",
|
||||
"depuracao": "External JTAG (requires probe, e.g. ESP-PROG)",
|
||||
"esp_idf_minimo": "v4.2",
|
||||
"arduino_core": "Yes (26 board definitions in official core)",
|
||||
"encapsulamento": "QFN56 (7×7 mm)",
|
||||
"modulos": "ESP32-S2-MINI-1, ESP32-S2-MINI-2, ESP32-S2-SOLO, ESP32-S2-SOLO-2 and 4 more",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-s2_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-s2_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html",
|
||||
"placa": "/placas/esp32-s2.png",
|
||||
"cor": "#28a745"
|
||||
},
|
||||
"ESP32-S3": {
|
||||
"nome_completo": "ESP32-S3",
|
||||
"icone": "🤖",
|
||||
"descricao": "Dual-core processor with accelerators for AI and signal processing",
|
||||
"arquitetura": "Xtensa® LX7 dual-core 32-bit",
|
||||
"nucleos": "2 (Dual-core)",
|
||||
"frequencia": "Up to 240 MHz",
|
||||
"coprocessador_ulp": "Yes (RISC-V)",
|
||||
"aceleradores_ia": "Yes (Vector Instructions for AI)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Yes (RSA/MPI up to 4096 bits)",
|
||||
"ecc": "No",
|
||||
"ecdsa": "No",
|
||||
"hmac": "Yes",
|
||||
"assinatura_digital": "Yes",
|
||||
"key_manager": "No",
|
||||
"rng": "Yes (hardware TRNG)",
|
||||
"criptografia_flash": "XTS-AES-128/256",
|
||||
"secure_boot": "V2 (RSA-3072)",
|
||||
"protecao_dpa": "No"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, up to 150 Mbps)",
|
||||
"bluetooth": "Bluetooth 5 (LE) and Bluetooth Mesh",
|
||||
"memoria_sram": "512 KB",
|
||||
"memoria_sram_rtc": "16 KB",
|
||||
"memoria_rom": "384 KB",
|
||||
"flash_externa": "Up to 1 GB via QSPI/Octal SPI",
|
||||
"psram_externa": "Up to 1 GB via QSPI/Octal SPI",
|
||||
"gpio": "45",
|
||||
"adc": "2x 12-bit SAR ADC, up to 20 channels",
|
||||
"dac": "No",
|
||||
"touch": "14 capacitive channels",
|
||||
"uart": "3",
|
||||
"spi": "4 (SPI0/1 for Flash, SPI2/3 for general use)",
|
||||
"i2c": "2",
|
||||
"i2s": "2",
|
||||
"pwm": "LED PWM (up to 8 channels), Motor PWM (6 channels)",
|
||||
"usb": "1 (USB OTG 1.1 Full-Speed) + 1 (USB Serial/JTAG)",
|
||||
"lcd": "8/16-bit RGB LCD interface",
|
||||
"camera": "8/16-bit DVP interface",
|
||||
"sdio": "1 (SD/SDIO/MMC Host)",
|
||||
"sensor_temperatura": "1 (internal)",
|
||||
"consumo_energia": {
|
||||
"active": "78 mW (~24 mA @3.3V)",
|
||||
"modem_sleep": "13-42 mA (40-80 MHz, depending on load)",
|
||||
"light_sleep": "240 µA (+40 to 200 µA from PSRAM)",
|
||||
"deep_sleep": "7 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C to 65/85/105°C",
|
||||
"temperatura_armazenamento": "-40°C to 150°C",
|
||||
"depuracao": "Integrated JTAG via USB (no external probe required)",
|
||||
"esp_idf_minimo": "v4.4",
|
||||
"arduino_core": "Yes (158 board definitions in official core)",
|
||||
"encapsulamento": "QFN56 (7×7 mm)",
|
||||
"modulos": "ESP32-S3-MINI-1, ESP32-S3-WROOM-1, ESP32-S3-WROOM-2",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-s3_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-s3_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/get-started/index.html",
|
||||
"placa": "/placas/esp32-s3.png",
|
||||
"cor": "#fd7e14"
|
||||
},
|
||||
"ESP32-S31": {
|
||||
"nome_completo": "ESP32-S31",
|
||||
"icone": "🌀",
|
||||
"descricao": "High-performance dual-core RISC-V processor at 320 MHz with Wi-Fi 6, Bluetooth 5.4 and Classic, Zigbee/Thread, Matter and AI acceleration",
|
||||
"arquitetura": "RISC-V dual-core 32-bit (HP) + RISC-V single-core (LP)",
|
||||
"nucleos": "2 (Dual-core HP) + 1 (Single-core LP)",
|
||||
"frequencia": "Up to 320 MHz",
|
||||
"coprocessador_ulp": "Yes (RISC-V, 40 MHz LP CPU)",
|
||||
"aceleradores_ia": "Yes (Custom AI and DSP extension XespV)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256 with GCM",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Yes (RSA/MPI up to 4096 bits)",
|
||||
"ecc": "Yes (P-192, P-256, P-384)",
|
||||
"ecdsa": "Yes (deterministic mode, RFC 6979)",
|
||||
"hmac": "Yes",
|
||||
"assinatura_digital": "Yes",
|
||||
"key_manager": "Yes",
|
||||
"rng": "Yes (hardware TRNG)",
|
||||
"criptografia_flash": "XTS-AES-128/256",
|
||||
"secure_boot": "V2 (RSA-3072)",
|
||||
"protecao_dpa": "Yes"
|
||||
},
|
||||
"wifi": "Wi-Fi 6 (802.11ax) 2.4 GHz",
|
||||
"bluetooth": "Bluetooth 5.4 LE and Bluetooth Classic",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0, Thread 1.4)",
|
||||
"matter": "Yes",
|
||||
"memoria_sram": "512 KB (HP SRAM)",
|
||||
"memoria_sram_rtc": "32 KB (LP SRAM)",
|
||||
"memoria_rom": "320 KB",
|
||||
"flash_externa": "Up to 256 MB via QSPI",
|
||||
"psram_externa": "16 MB or 32 MB octal DDR, in-package only (NRV16, NRV32)",
|
||||
"gpio": "60",
|
||||
"adc": "2x 12-bit SAR ADC, up to 16 channels",
|
||||
"dac": "Yes (2x 10-bit DAC and 2x 12-bit DAC)",
|
||||
"touch": "14 capacitive channels",
|
||||
"uart": "5 (4 UART + 1 LP UART)",
|
||||
"spi": "7 (6 SPI + 1 LP SPI)",
|
||||
"i2c": "3 (2 I2C + 1 LP I2C)",
|
||||
"i2s": "2",
|
||||
"pwm": "LED PWM (up to 8 channels), Motor PWM (MCPWM)",
|
||||
"usb": "1 (USB 2.0 High-Speed OTG and USB Serial/JTAG)",
|
||||
"can": "Yes (CAN FD Controller)",
|
||||
"sensor_temperatura": "1 (internal)",
|
||||
"consumo_energia": {
|
||||
"active": "Configurable optimized high-performance consumption",
|
||||
"light_sleep": "0.1-0.8 mA",
|
||||
"deep_sleep": "Low power with active LP CPU"
|
||||
},
|
||||
"temperatura_operacao": "-40°C to 85°C",
|
||||
"temperatura_armazenamento": "-40°C to 150°C",
|
||||
"depuracao": "Integrated JTAG via USB (no external probe required)",
|
||||
"esp_idf_minimo": "v6.1 in preview; official support starting from v6.1.1",
|
||||
"arduino_core": "Not yet supported by arduino-esp32 core",
|
||||
"encapsulamento": "QFN80 (8×8 mm)",
|
||||
"modulos": "ESP32-S31-WROOM-1, ESP32-S31-WROOM-3",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-s31_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-s31_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s31/get-started/index.html",
|
||||
"placa": "/placas/esp32-s31.png",
|
||||
"cor": "#ff2a5f",
|
||||
"sdio": "1 (SDIO Host 3.0)"
|
||||
},
|
||||
"ESP32-C2": {
|
||||
"nome_completo": "ESP32-C2 (ESP8684)",
|
||||
"icone": "🌱",
|
||||
"descricao": "Ultra-cost-effective and low-power RISC-V microcontroller with Wi-Fi 4 and Bluetooth 5.3 LE",
|
||||
"arquitetura": "RISC-V single-core 32-bit",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Up to 120 MHz",
|
||||
"seguranca": {
|
||||
"aes": "No",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "No",
|
||||
"ecc": "Yes (P-192, P-256)",
|
||||
"ecdsa": "No",
|
||||
"hmac": "No",
|
||||
"assinatura_digital": "No",
|
||||
"key_manager": "No",
|
||||
"rng": "Yes (hardware TRNG)",
|
||||
"criptografia_flash": "XTS-AES-128",
|
||||
"secure_boot": "V2 (ECDSA P-192 or P-256)",
|
||||
"protecao_dpa": "No"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, up to 72.2 Mbps)",
|
||||
"bluetooth": "Bluetooth 5.3 LE (certified)",
|
||||
"memoria_sram": "272 KB (16 KB for cache)",
|
||||
"memoria_sram_rtc": "No",
|
||||
"memoria_rom": "576 KB",
|
||||
"flash_externa": "Up to 16 MB via QSPI, but unavailable in retail variants (ESP8684H2X/H4X have 2 MB or 4 MB in package and do not expose flash pins)",
|
||||
"psram_externa": "No",
|
||||
"gpio": "14",
|
||||
"adc": "1x 12-bit SAR ADC, up to 5 channels",
|
||||
"dac": "No",
|
||||
"touch": "No",
|
||||
"uart": "2",
|
||||
"spi": "3 (SPI0/1 for internal Flash, SPI2 for general use)",
|
||||
"i2c": "1 (Master-only)",
|
||||
"i2s": "No",
|
||||
"pwm": "LED PWM (up to 6 channels)",
|
||||
"sensor_temperatura": "1 (internal)",
|
||||
"consumo_energia": {
|
||||
"active_cpu_120mhz": "10.7-15.6 mA (modem-sleep)",
|
||||
"light_sleep": "140 µA",
|
||||
"deep_sleep": "5 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C to 105°C",
|
||||
"temperatura_armazenamento": "-40°C to 150°C",
|
||||
"depuracao": "External JTAG (requires probe, e.g. ESP-PROG)",
|
||||
"esp_idf_minimo": "v5.0",
|
||||
"arduino_core": "Yes (1 board definition in official core)",
|
||||
"encapsulamento": "QFN24 (4×4 mm)",
|
||||
"modulos": "ESP8684-MINI-1, ESP8684-WROOM-01C, ESP8684-WROOM-02C, ESP8684-WROOM-02UC and 5 more",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-c2_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-c2_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c2/get-started/index.html",
|
||||
"placa": "/placas/esp32-c2.png",
|
||||
"cor": "#8c52ff"
|
||||
},
|
||||
"ESP32-C3": {
|
||||
"nome_completo": "ESP32-C3",
|
||||
"icone": "💎",
|
||||
"descricao": "Ultra-low-power RISC-V processor",
|
||||
"arquitetura": "RISC-V single-core 32-bit",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Up to 160 MHz",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "Yes (RSA/MPI up to 3072 bits)",
|
||||
"ecc": "No",
|
||||
"ecdsa": "No",
|
||||
"hmac": "Yes",
|
||||
"assinatura_digital": "Yes",
|
||||
"key_manager": "No",
|
||||
"rng": "Yes (hardware TRNG)",
|
||||
"criptografia_flash": "XTS-AES-128",
|
||||
"secure_boot": "V2 (RSA-3072), starting from rev v0.3 (ECO3)",
|
||||
"protecao_dpa": "No"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, up to 150 Mbps)",
|
||||
"bluetooth": "Bluetooth 5 (LE) and Bluetooth Mesh",
|
||||
"memoria_sram": "400 KB",
|
||||
"memoria_sram_rtc": "8 KB",
|
||||
"memoria_rom": "384 KB",
|
||||
"flash_externa": "Up to 16 MB via QSPI",
|
||||
"psram_externa": "No",
|
||||
"gpio": "22",
|
||||
"adc": "2x 12-bit SAR ADC, up to 6 channels",
|
||||
"dac": "No",
|
||||
"touch": "No",
|
||||
"uart": "2",
|
||||
"spi": "3 (SPI0/1 for Flash, SPI2 for general use)",
|
||||
"i2c": "1",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (up to 6 channels)",
|
||||
"usb": "1 (USB Serial/JTAG)",
|
||||
"sensor_temperatura": "1 (internal)",
|
||||
"consumo_energia": {
|
||||
"active_cpu_160mhz": "20 mA",
|
||||
"active_wifi_tx_peak": "335 mA",
|
||||
"modem_sleep_cpu_160mhz": "16-28 mA",
|
||||
"light_sleep": "130 µA",
|
||||
"deep_sleep": "5 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C to 105°C (85°C on ESP32-C3FN4)",
|
||||
"temperatura_armazenamento": "-40°C to 150°C",
|
||||
"depuracao": "Integrated JTAG via USB (no external probe required)",
|
||||
"esp_idf_minimo": "v4.3",
|
||||
"arduino_core": "Yes (29 board definitions in official core)",
|
||||
"encapsulamento": "QFN32 (5×5 mm) and QFN28 (4×4 mm)",
|
||||
"modulos": "ESP32-C3-MINI-1, ESP32-C3-WROOM-02",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-c3_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-c3_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/get-started/index.html",
|
||||
"placa": "/placas/esp32-c3.png",
|
||||
"cor": "#20c997"
|
||||
},
|
||||
"ESP32-C5": {
|
||||
"nome_completo": "ESP32-C5",
|
||||
"icone": "📶",
|
||||
"descricao": "The first with dual-band Wi-Fi 6 and Bluetooth 6.0 support, equipped with RISC-V CPU and ULP coprocessor",
|
||||
"arquitetura": "RISC-V single-core 32-bit (HP) + RISC-V single-core (LP)",
|
||||
"nucleos": "1 (Single-core HP) + 1 (Single-core LP)",
|
||||
"frequencia": "Up to 240 MHz",
|
||||
"coprocessador_ulp": "Yes (RISC-V, 48 MHz LP CPU)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Yes (RSA/MPI up to 3072 bits)",
|
||||
"ecc": "Yes (P-192, P-256, P-384)",
|
||||
"ecdsa": "Yes (deterministic mode, RFC 6979)",
|
||||
"hmac": "Yes",
|
||||
"assinatura_digital": "Yes",
|
||||
"key_manager": "Yes",
|
||||
"rng": "Yes (hardware TRNG)",
|
||||
"criptografia_flash": "XTS-AES-128/256",
|
||||
"secure_boot": "V2 (RSA-3072 or ECDSA P-256/P-384)",
|
||||
"protecao_dpa": "Yes"
|
||||
},
|
||||
"wifi": "Wi-Fi 6 (802.11ax) dual-band 2.4 GHz and 5 GHz",
|
||||
"bluetooth": "Bluetooth 5 (LE) (Bluetooth Core 6.0 certified)",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0, Thread 1.4)",
|
||||
"matter": "Yes",
|
||||
"memoria_sram": "384 KB",
|
||||
"memoria_sram_rtc": "16 KB",
|
||||
"memoria_rom": "320 KB",
|
||||
"flash_externa": "Up to 16 MB via QSPI",
|
||||
"psram_externa": "Yes, via SPI (flash/PSRAM controller with cache)",
|
||||
"gpio": "29",
|
||||
"adc": "1x 12-bit SAR ADC, up to 6 channels",
|
||||
"dac": "No",
|
||||
"touch": "No",
|
||||
"uart": "3 (2 UART + 1 LP UART)",
|
||||
"spi": "3",
|
||||
"i2c": "2 (1 I2C + 1 LP I2C)",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (up to 6 channels), Motor PWM",
|
||||
"usb": "1 (USB Serial/JTAG)",
|
||||
"sensor_temperatura": "1 (internal)",
|
||||
"consumo_energia": {
|
||||
"active_wifi": "up to 377 mA (TX at 5 GHz)",
|
||||
"light_sleep": "60-250 µA",
|
||||
"deep_sleep": "12 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C to 105°C",
|
||||
"temperatura_armazenamento": "-40°C to 150°C",
|
||||
"depuracao": "Integrated JTAG via USB (no external probe required)",
|
||||
"esp_idf_minimo": "v5.5.2",
|
||||
"arduino_core": "Yes (10 board definitions in official core)",
|
||||
"encapsulamento": "QFN48 (6×6 mm)",
|
||||
"modulos": "ESP32-C5-MINI-1, ESP32-C5-WROOM-1",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-c5_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-c5_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c5/get-started/index.html",
|
||||
"placa": "/placas/esp32-c5.png",
|
||||
"cor": "#6f42c1",
|
||||
"sdio": "1 (SDIO Slave, starting from rev v1.0)",
|
||||
"can": "2 (CAN FD)"
|
||||
},
|
||||
"ESP32-C6": {
|
||||
"nome_completo": "ESP32-C6",
|
||||
"icone": "🌐",
|
||||
"descricao": "Advanced security features, Wi-Fi 6, Bluetooth 6.0, Zigbee and Thread with Matter support",
|
||||
"arquitetura": "RISC-V single-core 32-bit (HP) + RISC-V single-core (LP)",
|
||||
"nucleos": "1 (Single-core HP) + 1 (Single-core LP)",
|
||||
"frequencia": "Up to 160 MHz",
|
||||
"coprocessador_ulp": "Yes (RISC-V, 20 MHz LP CPU)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "Yes (RSA/MPI up to 3072 bits)",
|
||||
"ecc": "Yes (P-192, P-256)",
|
||||
"ecdsa": "No",
|
||||
"hmac": "Yes",
|
||||
"assinatura_digital": "Yes",
|
||||
"key_manager": "No",
|
||||
"rng": "Yes (hardware TRNG)",
|
||||
"criptografia_flash": "XTS-AES-128",
|
||||
"secure_boot": "V2 (RSA-3072 or ECDSA)",
|
||||
"protecao_dpa": "Yes"
|
||||
},
|
||||
"wifi": "Wi-Fi 6 (802.11ax) 2.4 GHz",
|
||||
"bluetooth": "Bluetooth 5 (LE) (Bluetooth 5.3 certified)",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0, Thread 1.3)",
|
||||
"matter": "Yes",
|
||||
"memoria_sram": "512 KB",
|
||||
"memoria_sram_rtc": "16 KB",
|
||||
"memoria_rom": "320 KB",
|
||||
"flash_externa": "Up to 16 MB via QSPI",
|
||||
"psram_externa": "No",
|
||||
"gpio": "30",
|
||||
"adc": "1x 12-bit SAR ADC, up to 7 channels",
|
||||
"dac": "No",
|
||||
"touch": "No",
|
||||
"uart": "3 (2 UART + 1 LP UART)",
|
||||
"spi": "3",
|
||||
"i2c": "2 (1 I2C + 1 LP I2C)",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (up to 6 channels), Motor PWM",
|
||||
"usb": "1 (USB Serial/JTAG)",
|
||||
"sdio": "1 (SDIO 2.0 Slave)",
|
||||
"sensor_temperatura": "1 (internal)",
|
||||
"consumo_energia": {
|
||||
"active_wifi6": "252-354 mA (TX)",
|
||||
"light_sleep": "35-180 µA",
|
||||
"deep_sleep": "7 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C to 105°C",
|
||||
"temperatura_armazenamento": "-40°C to 150°C",
|
||||
"depuracao": "Integrated JTAG via USB (no external probe required)",
|
||||
"esp_idf_minimo": "v5.1",
|
||||
"arduino_core": "Yes (21 board definitions in official core)",
|
||||
"encapsulamento": "QFN40 (5×5 mm) and QFN32 (5×5 mm)",
|
||||
"modulos": "ESP32-C6-MINI-1, ESP32-C6-WROOM-1",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-c6_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-c6_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/get-started/index.html",
|
||||
"placa": "/placas/esp32-c6.png",
|
||||
"cor": "#17a2b8"
|
||||
},
|
||||
"ESP32-C61": {
|
||||
"nome_completo": "ESP32-C61",
|
||||
"icone": "🛰️",
|
||||
"descricao": "Cost-effective 160 MHz RISC-V microcontroller with Wi-Fi 6, Bluetooth 6.0 LE and in-package Flash/PSRAM support",
|
||||
"arquitetura": "RISC-V single-core 32-bit",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Up to 160 MHz",
|
||||
"seguranca": {
|
||||
"aes": "No",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "No",
|
||||
"ecc": "Yes (P-192, P-256)",
|
||||
"ecdsa": "Yes (deterministic mode, RFC 6979)",
|
||||
"hmac": "No",
|
||||
"assinatura_digital": "No",
|
||||
"key_manager": "No",
|
||||
"rng": "Yes (hardware TRNG)",
|
||||
"criptografia_flash": "XTS-AES-128",
|
||||
"secure_boot": "V2 (ECDSA)",
|
||||
"protecao_dpa": "Yes"
|
||||
},
|
||||
"wifi": "Wi-Fi 6 (802.11ax) 2.4 GHz",
|
||||
"bluetooth": "Bluetooth 5 (LE) (Bluetooth Core 6.0 certified)",
|
||||
"zigbee_thread": "No",
|
||||
"matter": "Yes (via Wi-Fi)",
|
||||
"memoria_sram": "320 KB",
|
||||
"memoria_sram_rtc": "No",
|
||||
"memoria_rom": "256 KB",
|
||||
"flash_externa": "Up to 16 MB via QSPI (models with 4 MB or 8 MB integrated in package)",
|
||||
"psram_externa": "Up to 16 MB via QSPI (models with 2 MB or 8 MB integrated in package)",
|
||||
"gpio": "30",
|
||||
"adc": "1x 12-bit SAR ADC, up to 4 channels",
|
||||
"dac": "No",
|
||||
"touch": "No",
|
||||
"uart": "3",
|
||||
"spi": "3 (2 for Flash/PSRAM, 1 for general use)",
|
||||
"i2c": "1",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (up to 6 channels)",
|
||||
"usb": "1 (USB Serial/JTAG)",
|
||||
"sdio": "1 (SDIO 2.0 Slave)",
|
||||
"sensor_temperatura": "1 (internal)",
|
||||
"consumo_energia": {
|
||||
"active": "240-360 mA (TX)",
|
||||
"light_sleep": "50-200 µA",
|
||||
"deep_sleep": "10 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C to 105°C",
|
||||
"temperatura_armazenamento": "-40°C to 150°C",
|
||||
"depuracao": "Integrated JTAG via USB (no external probe required)",
|
||||
"esp_idf_minimo": "v5.5.2",
|
||||
"arduino_core": "Yes (1 board definition in official core)",
|
||||
"encapsulamento": "QFN40 (5×5 mm) or LGA40 (5×5 mm)",
|
||||
"modulos": "ESP32-C61-MINI-1, ESP32-C61-WROOM-1",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-c61_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-c61_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c61/get-started/index.html",
|
||||
"placa": "/placas/esp32-c61.png",
|
||||
"cor": "#0dcaf0"
|
||||
},
|
||||
"ESP32-P4": {
|
||||
"nome_completo": "ESP32-P4",
|
||||
"icone": "⚡",
|
||||
"descricao": "High performance with dual-core RISC-V processor at 400 MHz, AI accelerators and rich media interfaces",
|
||||
"arquitetura": "32-bit RISC-V high-performance (HP) dual-core + low-power (LP) single-core",
|
||||
"nucleos": "2 (Dual-core HP) + 1 (Single-core LP)",
|
||||
"frequencia": "Up to 400 MHz (HP, rev v3.x; 360 MHz in v1.x); LP up to 40 MHz",
|
||||
"coprocessador_ulp": "Yes (RISC-V, 40 MHz LP CPU)",
|
||||
"aceleradores_ia": "Yes (Vector Instructions, AI accelerators)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256 with GCM",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Yes (RSA/MPI up to 4096 bits)",
|
||||
"ecc": "Yes (P-192, P-256, P-384)",
|
||||
"ecdsa": "Yes (deterministic mode, RFC 6979)",
|
||||
"hmac": "Yes",
|
||||
"assinatura_digital": "Yes",
|
||||
"key_manager": "Yes",
|
||||
"rng": "Yes (hardware TRNG)",
|
||||
"criptografia_flash": "XTS-AES-128/256",
|
||||
"secure_boot": "V2 (RSA-3072 or ECDSA)",
|
||||
"protecao_dpa": "No"
|
||||
},
|
||||
"wifi": "No",
|
||||
"bluetooth": "No",
|
||||
"ethernet": "Yes (Integrated Ethernet MAC)",
|
||||
"memoria_sram": "768 KB",
|
||||
"memoria_sram_rtc": "32 KB",
|
||||
"memoria_rom": "128 KB (HP ROM) + 16 KB (LP ROM)",
|
||||
"flash_externa": "Up to 128 MB via QSPI/Octal SPI",
|
||||
"psram_externa": "16 MB or 32 MB integrated in package (OPI/HPI, 1.8 V)",
|
||||
"gpio": "55",
|
||||
"adc": "2x 12-bit SAR ADC, up to 14 channels",
|
||||
"dac": "No",
|
||||
"touch": "Yes (capacitive touch sensor)",
|
||||
"uart": "6 (5 UART + 1 LP UART)",
|
||||
"spi": "3",
|
||||
"i2c": "3 (2 I2C + 1 LP I2C)",
|
||||
"i2s": "4 (3 I2S + 1 LP I2S)",
|
||||
"pwm": "LED PWM (up to 8 channels), Motor PWM (6 channels)",
|
||||
"usb": "USB 2.0 High-Speed OTG + USB 2.0 Full-Speed OTG + USB Serial/JTAG",
|
||||
"mipi_csi": "MIPI CSI camera interface",
|
||||
"mipi_dsi": "MIPI DSI display interface",
|
||||
"lcd": "8/16/24-bit LCD interface",
|
||||
"camera": "8/16-bit DVP interface",
|
||||
"sdio": "1 SD/MMC Host controller (SDHOST)",
|
||||
"sensor_temperatura": "1 (internal)",
|
||||
"consumo_energia": {
|
||||
"active": "15-150 mA (40 a 400 MHz, depending on load)",
|
||||
"light_sleep": "75-800 µA",
|
||||
"deep_sleep": "12 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C to 85°C",
|
||||
"temperatura_armazenamento": "-40°C to 150°C",
|
||||
"depuracao": "Integrated JTAG via USB (no external probe required)",
|
||||
"esp_idf_minimo": "v5.3",
|
||||
"arduino_core": "Yes (7 board definitions in official core)",
|
||||
"encapsulamento": "QFN104 (10×10 mm)",
|
||||
"modulos": "No module in official catalog (bare chip only)",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-p4-chip-revision-v1.3_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-p4-chip-revision-v1.3_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/get-started/index.html",
|
||||
"placa": "/placas/esp32-p4.png",
|
||||
"cor": "#ffc107"
|
||||
},
|
||||
"ESP32-H2": {
|
||||
"nome_completo": "ESP32-H2",
|
||||
"icone": "🔋",
|
||||
"descricao": "Focused on ultra-low power with Bluetooth 6.0, Zigbee and Thread. No Wi-Fi support",
|
||||
"arquitetura": "RISC-V single-core 32-bit",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Up to 96 MHz",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "Yes (RSA/MPI up to 3072 bits)",
|
||||
"ecc": "Yes (P-192, P-256)",
|
||||
"ecdsa": "Yes (deterministic mode, RFC 6979)",
|
||||
"hmac": "Yes",
|
||||
"assinatura_digital": "Yes",
|
||||
"key_manager": "No",
|
||||
"rng": "Yes (hardware TRNG)",
|
||||
"criptografia_flash": "XTS-AES-128",
|
||||
"secure_boot": "V2 (RSA-3072 or ECDSA)",
|
||||
"protecao_dpa": "Yes"
|
||||
},
|
||||
"wifi": "No",
|
||||
"bluetooth": "Bluetooth 5 (LE) (Bluetooth 5.3 certified)",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0, Thread 1.4)",
|
||||
"matter": "Yes",
|
||||
"memoria_sram": "320 KB",
|
||||
"memoria_sram_rtc": "4 KB (LP Memory)",
|
||||
"memoria_rom": "128 KB",
|
||||
"flash_externa": "Up to 16 MB via QSPI",
|
||||
"psram_externa": "No",
|
||||
"gpio": "19",
|
||||
"adc": "1x 12-bit SAR ADC, up to 5 channels",
|
||||
"dac": "No",
|
||||
"touch": "No",
|
||||
"uart": "2",
|
||||
"spi": "3",
|
||||
"i2c": "2",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (up to 6 channels)",
|
||||
"usb": "1 (USB Serial/JTAG)",
|
||||
"sensor_temperatura": "1 (internal)",
|
||||
"consumo_energia": {
|
||||
"active": "24-140 mA (radio, from -24 to 20 dBm)",
|
||||
"light_sleep": "25-85 µA",
|
||||
"deep_sleep": "7 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C to 105°C",
|
||||
"temperatura_armazenamento": "-40°C to 150°C",
|
||||
"depuracao": "Integrated JTAG via USB (no external probe required)",
|
||||
"esp_idf_minimo": "v5.1",
|
||||
"arduino_core": "Yes (3 board definitions in official core)",
|
||||
"encapsulamento": "QFN32 (4×4 mm)",
|
||||
"modulos": "ESP32-H2-MINI-1, ESP32-H2-WROOM-02C",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-h2_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-h2_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32h2/get-started/index.html",
|
||||
"placa": "/placas/esp32-h2.png",
|
||||
"cor": "#6c757d"
|
||||
},
|
||||
"ESP32-H4": {
|
||||
"nome_completo": "ESP32-H4",
|
||||
"icone": "🛡️",
|
||||
"descricao": "Ultra-high energy efficiency dual-core RISC-V SoC with Bluetooth 5.4 LE (LE Audio) and IEEE 802.15.4 for Thread, Zigbee and Matter. No Wi-Fi",
|
||||
"status_documentacao": "Preliminary documentation: Espressif has not yet published the datasheet or technical reference manual for ESP32-H4. The data below comes from the official product announcement and ESP-IDF hardware definitions (soc_caps), and may change before release.",
|
||||
"arquitetura": "RISC-V dual-core 32-bit",
|
||||
"nucleos": "2 (Dual-core)",
|
||||
"frequencia": "Up to 96 MHz",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "No",
|
||||
"ecc": "Yes (P-192, P-256, P-384)",
|
||||
"ecdsa": "Yes (deterministic mode, RFC 6979)",
|
||||
"hmac": "Yes",
|
||||
"assinatura_digital": "No",
|
||||
"key_manager": "No",
|
||||
"rng": "Yes (hardware TRNG)",
|
||||
"criptografia_flash": "XTS-AES-128/256",
|
||||
"secure_boot": "Yes in hardware; not yet enabled in ESP-IDF)",
|
||||
"protecao_dpa": "No"
|
||||
},
|
||||
"wifi": "No",
|
||||
"bluetooth": "Bluetooth 5.4 LE (Bluetooth 6.0 certified; LE Audio, isochronous channels BIS/CIS, PAwR, Connection Subrating and Direction Finding AoA/AoD)",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0, Thread 1.4)",
|
||||
"matter": "Yes",
|
||||
"memoria_sram": "384 KB",
|
||||
"memoria_sram_rtc": "Yes (LP SRAM)",
|
||||
"memoria_rom": "128 KB",
|
||||
"flash_externa": "Yes, via QSPI (4 MB integrated in package on ESP32-H4HF4)",
|
||||
"psram_externa": "Yes (2 MB integrated in package on ESP32-H4HR2)",
|
||||
"gpio": "40",
|
||||
"adc": "1x 12-bit SAR ADC, up to 5 channels",
|
||||
"dac": "No",
|
||||
"touch": "15 capacitive channels (version 3, with waterproof and proximity)",
|
||||
"uart": "2",
|
||||
"spi": "3",
|
||||
"i2c": "2",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (up to 8 channels), Motor PWM (MCPWM)",
|
||||
"can": "1 (CAN 2.0, TWAI®)",
|
||||
"usb": "1 (USB OTG 1.1) + 1 (USB Serial/JTAG)",
|
||||
"sensor_temperatura": "1 (internal)",
|
||||
"consumo_energia": {
|
||||
"active": "Not disclosed (preliminary documentation)"
|
||||
},
|
||||
"temperatura_operacao": "-40°C to 105°C",
|
||||
"temperatura_armazenamento": "Not disclosed (preliminary documentation)",
|
||||
"depuracao": "Integrated JTAG via USB (no external probe required)",
|
||||
"esp_idf_minimo": "v6.0 preview (no stable support)",
|
||||
"arduino_core": "Not yet supported by arduino-esp32 core",
|
||||
"encapsulamento": "QFN56 (6×6 mm)",
|
||||
"modulos": "ESP32-H4-WROOM-1",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32h4/get-started/index.html",
|
||||
"cor": "#e83e8c"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "ANT",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Conexão de antena de RF (Wi-Fi e Bluetooth)"],
|
||||
"categorias": ["Antena", "RF"],
|
||||
"avisos": ["Pino de RF dedicado. Evite traçar pistas longas ou sem casamento de impedância de 50 ohms."]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDDA3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação analógica de 3.3V"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão recomendada: 3.3V (3.0V a 3.6V)",
|
||||
"Fornece energia para os circuitos analógicos e de RF do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDDA3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação analógica de 3.3V"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão recomendada: 3.3V (3.0V a 3.6V)",
|
||||
"Fornece energia para os circuitos analógicos e de RF do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "GPIO0",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC1 Canal 0"]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "GPIO1",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"ADC1_CH1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC1 Canal 1"]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "GPIO2",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO2",
|
||||
"ADC1_CH2",
|
||||
"FSPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Mapeado para a função SPI MISO (FSPIQ) por padrão na inicialização do flash"]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "CHIP_EN",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Habilitar o chip (Power-up / Reset)"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Ativo Alto. Puxe para nível alto para inicializar o chip.",
|
||||
"Não deixe este pino flutuando. Use um circuito RC de atraso externo para inicialização estável."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "GPIO3",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"ADC1_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC1 Canal 3"]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "GPIO4",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"MTMS",
|
||||
"FSPIQ",
|
||||
"ADC1_CH4"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"SPI",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Pino multifuncional: JTAG MTMS, SPI2 MISO e ADC1 Canal 4.",
|
||||
"Pode ser usado para depuração JTAG em conjunto com outros pinos JTAG."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "GPIO5",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"MTDI",
|
||||
"FSPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino multifuncional: JTAG MTDI e SPI2 Write Protect (FSPIWP)."]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "VDD3P3_RTC",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação do domínio de RTC e IOs de baixo consumo"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Tensão recomendada: 3.3V"]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "GPIO6",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"MTCK",
|
||||
"FSPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino multifuncional: JTAG MTCK e SPI2 Clock (FSPICLK)."]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "GPIO7",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO7",
|
||||
"MTDO",
|
||||
"FSPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino multifuncional: JTAG MTDO e SPI2 MOSI (FSPID)."]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": ["GPIO8"],
|
||||
"categorias": ["GPIO", "Strapping"],
|
||||
"avisos": [
|
||||
"Pino de Strapping para controle de boot.",
|
||||
"Em conjunto com o GPIO9, seleciona o modo de inicialização do SoC (deve estar em 1 durante o reset para Joint Download Boot se GPIO9=0)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": ["GPIO9"],
|
||||
"categorias": ["GPIO", "Strapping"],
|
||||
"avisos": [
|
||||
"Pino de Strapping principal. Nível alto (1) no reset activa SPI Boot (padrão via pull-up fraco).",
|
||||
"Nível baixo (0) no reset coloca o chip no modo de download UART/SPI."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"FSPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino multifuncional: SPI2 Chip Select 0 (FSPICS0)."]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "VDD3P3_CPU",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação digital da CPU e IOs correspondentes (3.3V)"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Tensão recomendada: 3.3V"]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "GPIO18",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": ["GPIO18"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "GPIO19",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO19",
|
||||
"U0RXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": ["Pino de recepção UART0 (Serial RX por padrão para gravação e monitoramento)."]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "GPIO20",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"U0TXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": ["Pino de transmissão UART0 (Serial TX por padrão para gravação e monitoramento)."]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação de entrada analógica de 3.3V"],
|
||||
"categorias": ["Power"]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Conexão externa do cristal oscilador (Saída)"],
|
||||
"categorias": ["Clock"]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Conexão externa do cristal oscilador (Entrada)"],
|
||||
"categorias": ["Clock"]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação de entrada analógica de 3.3V"],
|
||||
"categorias": ["Power"]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GND",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Pino de aterramento central (Exposed Pad)"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Deve ser devidamente soldado ao plano de terra (GND) da PCB para desempenho estável e dissipação térmica."]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,533 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "LNA_IN",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Entrada e saída dos sinais de RF (Wi-Fi e Bluetooth) para a antena"],
|
||||
"categorias": ["Antena"],
|
||||
"avisos": ["Consulte o item 2.4 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "XTAL_32K_P",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"XTAL_32K_P",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "XTAL_32K_N",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"XTAL_32K_N",
|
||||
"ADC1_CH1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "GPIO2",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO2",
|
||||
"ADC1_CH2",
|
||||
"FSPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Na verdade, esse pino não determina o modo de boot, mas é recomendado conectar ele com um pull-up para evitar glitches (consulte o item 3.1 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "CHIP_EN",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Habilitar o chip"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Colocar este pino em nível alto habilitará o funcionamento do chip",
|
||||
"Colocar este pino em nível baixo desabilitará o funcionamento do chip",
|
||||
"Não deixe este pino flutuando, utilize um resistor de pull-up externo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "GPIO3",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"ADC1_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "MTMS",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"ADC1_CH4",
|
||||
"FSPIHD",
|
||||
"MTMS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "MTDI",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"ADC2_CH0",
|
||||
"FSPIWP",
|
||||
"MTDI"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "VDD3P3_RTC",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio de baixo consumo e parte do domínio digital"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "MTCK",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"FSPICLK",
|
||||
"MTCK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "MTDO",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO7",
|
||||
"FSPID",
|
||||
"MTDO"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": ["GPIO8"],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Utilizado para controlar o modo de boot do chip (consulte o item 3.1 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": ["GPIO9"],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado para controlar o modo de boot do chip (consulte o item 3.1 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"FSPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Após o reset, este pino estará configurado como entrada"]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "VDD3P3_CPU",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio digital"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "VDD_SPI",
|
||||
"tipo": "power",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"Entrada/saída da alimentação da flash interna/externa",
|
||||
"GPIO11"
|
||||
],
|
||||
"categorias": [
|
||||
"Power",
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip",
|
||||
"Só pode ser utilizado como GPIO se a memória flash estiver sendo alimentada por uma fonte externa"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "SPIHD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI", "VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"SPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "SPIWP",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI", "VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"SPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "SPICS0",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI", "VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO14",
|
||||
"SPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "SPICLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI", "VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO15",
|
||||
"SPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "SPID",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI", "VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO16",
|
||||
"SPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "SPIQ",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI", "VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"SPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GPIO18",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO18",
|
||||
"USB_D-"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": ["Por padrão, este pino é utilizado para USB Serial/JTAG"]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "GPIO19",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO19",
|
||||
"USB_D+"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": ["Por padrão, este pino é utilizado para USB Serial/JTAG"]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "U0RXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"U0RXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "U0TXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO21",
|
||||
"U0TXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará com o pull-up interno ativado",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Entrada/Saída negativa de clock"],
|
||||
"categorias": ["Clock"],
|
||||
"avisos": ["Consulte o item 2.3.2 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Entrada/Saída positiva de clock"],
|
||||
"categorias": ["Clock"],
|
||||
"avisos": ["Consulte o item 2.3.2 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": ["Referência elétrica do circuito (terra)"],
|
||||
"categorias": ["GND"]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,776 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "VDDA6",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": ["Referência elétrica do circuito (terra)"],
|
||||
"categorias": ["GND"]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDDA7",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Entrada/Saída negativa de clock"],
|
||||
"categorias": ["Clock"],
|
||||
"avisos": ["Consulte o item 2.3.3 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Entrada/Saída positiva de clock"],
|
||||
"categorias": ["Clock"],
|
||||
"avisos": ["Consulte o item 2.3.3 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "VDDA8",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "CHIP_PU",
|
||||
"tipo": "analog",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": ["Habilitar o chip"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Colocar este pino em nível alto habilitará o funcionamento do chip",
|
||||
"Colocar este pino em nível baixo desabilitará o funcionamento do chip",
|
||||
"Não deixe este pino flutuando, utilize um resistor de pull-up externo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio digital de baixo consumo"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "XTAL_32K_P",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"LP_GDIO0",
|
||||
"XTAL_32K_P",
|
||||
"LP_UART_DTRN"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"Clock",
|
||||
"UART"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "XTAL_32K_N",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"LP_GDIO1",
|
||||
"XTAL_32K_N",
|
||||
"LP_UART_DSRN",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"Clock",
|
||||
"UART",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "MTMS",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO2",
|
||||
"LP_GDIO2",
|
||||
"LP_UART_RTSN",
|
||||
"LP_I2C_SDA",
|
||||
"ADC1_CH1",
|
||||
"FSPIQ",
|
||||
"MTMS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"I2C",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"A função de I2C_SDA está disponível no modo de baixo consumo (LP)",
|
||||
"Pino utilizado para debugging",
|
||||
"Utilizado para controlar a frequência do cristal oscilador do chip (consulte o item 3.5 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "MTDI",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"LP_GDIO3",
|
||||
"LP_UART_CTSN",
|
||||
"LP_I2C_SCL",
|
||||
"ADC1_CH2",
|
||||
"MTDI"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"I2C",
|
||||
"ADC",
|
||||
"JTAG",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"A função de I2C_SDA está disponível no modo de baixo consumo (LP)",
|
||||
"Pino utilizado para debugging",
|
||||
"Utilizado para controlar a temporização do SDIO Slave (consulte o item 3.2 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "MTCK",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"LP_GDIO4",
|
||||
"LP_UART_RXD",
|
||||
"ADC1_CH3",
|
||||
"FSPIHD",
|
||||
"MTCK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "MTDO",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"LP_GDIO5",
|
||||
"LP_UART_TXD",
|
||||
"ADC1_CH4",
|
||||
"FSPIWP",
|
||||
"MTDO"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO6",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"LP_GDIO6",
|
||||
"ADC1_CH5",
|
||||
"FSPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO7",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO7",
|
||||
"FSPID",
|
||||
"SDIO_DATA1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Utilizado para controlar a fonte de sinais JTAG (consulte o item 3.4 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO8",
|
||||
"SDIO_DATA0",
|
||||
"PAD_COMP0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD"
|
||||
],
|
||||
"avisos": ["Após o reset, este pino estará configurado como entrada"]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO9",
|
||||
"SDIO_CLK",
|
||||
"PAD_COMP1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD"
|
||||
],
|
||||
"avisos": ["Após o reset, este pino estará configurado como entrada"]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"FSPICS0",
|
||||
"SDIO_CMD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"SD"
|
||||
],
|
||||
"avisos": ["Após o reset, este pino estará configurado como entrada"]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "U0TXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO11",
|
||||
"U0TXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará com o pull-up interno ativado",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "U0RXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"U0RXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "GPIO13",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"USB_D-",
|
||||
"SDIO_DATA3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Por padrão, este pino é utilizado para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "GPIO14",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO14",
|
||||
"USB_D+",
|
||||
"SDIO_DATA4"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno para USB ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno para USB ativado",
|
||||
"Por padrão, este pino é utilizado para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "VDDPST2",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio digital de alto desempenho e parte do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "SPICS1",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": [
|
||||
"GPIO15",
|
||||
"SPICS1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "SPICS0",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": [
|
||||
"GPIO16",
|
||||
"SPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "SPIQ",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"SPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "SPIWP",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": [
|
||||
"GPIO18",
|
||||
"SPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "VDD_SPI",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Saída de alimentação para a flash externa",
|
||||
"GPIO19"
|
||||
],
|
||||
"categorias": [
|
||||
"Power",
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip",
|
||||
"Só pode ser utilizado como GPIO se a memória flash externa estiver sendo alimentada por uma fonte externa"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "SPIHD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"SPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "SPICLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": [
|
||||
"GPIO21",
|
||||
"SPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "SPID",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": [
|
||||
"GPIO22",
|
||||
"SPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "GPIO23",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST3"],
|
||||
"funcoes": ["GPIO23"],
|
||||
"categorias": ["GPIO"],
|
||||
"avisos": ["Após o reset, este pino estará configurado como entrada"]
|
||||
},
|
||||
{
|
||||
"numero": "34",
|
||||
"nome": "GPIO24",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST3"],
|
||||
"funcoes": ["GPIO24"],
|
||||
"categorias": ["GPIO"],
|
||||
"avisos": ["Após o reset, este pino estará configurado como entrada"]
|
||||
},
|
||||
{
|
||||
"numero": "35",
|
||||
"nome": "GPIO25",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST3"],
|
||||
"funcoes": ["GPIO25"],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Utilizado para controlar a temporização do SDIO Slave (consulte o item 3.4 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "36",
|
||||
"nome": "GPIO26",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST3"],
|
||||
"funcoes": ["GPIO26"],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Utilizado para controlar o modo de boot do chip (consulte o item 3.1 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "37",
|
||||
"nome": "GPIO27",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST3"],
|
||||
"funcoes": ["GPIO27"],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado para controlar o modo de boot do chip (consulte o item 3.1 do datasheet para mais detalhes)",
|
||||
"Utilizado para controlar a exibição de mensagens ROM na UART0 (consulte o item 3.3 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "38",
|
||||
"nome": "GPIO28",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST3"],
|
||||
"funcoes": ["GPIO28"],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado para controlar o modo de boot do chip (consulte o item 3.1 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "39",
|
||||
"nome": "VDDPST3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio digital de alto desempenho"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "40",
|
||||
"nome": "VDDA1",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "41",
|
||||
"nome": "VDDA2",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "42",
|
||||
"nome": "ANT_2G",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Conexão da antena RF para a banda de 2 GHz"],
|
||||
"categorias": ["Antena"],
|
||||
"avisos": ["Consulte o item 2.4 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "43",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": ["Referência elétrica do circuito (terra)"],
|
||||
"categorias": ["GND"]
|
||||
},
|
||||
{
|
||||
"numero": "44",
|
||||
"nome": "VDDA3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "44",
|
||||
"nome": "VDDA4",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "45",
|
||||
"nome": "VDDA5",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "47",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": ["Referência elétrica do circuito (terra)"],
|
||||
"categorias": ["GND"]
|
||||
},
|
||||
{
|
||||
"numero": "48",
|
||||
"nome": "ANT_5G",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Conexão da antena RF para a banda de 5 GHz"],
|
||||
"categorias": ["Antena"],
|
||||
"avisos": ["Consulte o item 2.4 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,715 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "ANT",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Conexão da antena RF"],
|
||||
"categorias": ["Antena"],
|
||||
"avisos": ["Consulte o item 2.4 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDDA3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDDA3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "CHIP_PU",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Habilitar o chip"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Colocar este pino em nível alto habilitará o funcionamento do chip",
|
||||
"Colocar este pino em nível baixo desabilitará o funcionamento do chip",
|
||||
"Não deixe este pino flutuando, utilize um resistor de pull-up externo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio digital de baixo consumo e parte do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "XTAL_32K_P",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"LP_GDIO0",
|
||||
"XTAL_32K_P",
|
||||
"LP_UART_DTRN",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"Clock",
|
||||
"UART"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "XTAL_32K_N",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"LP_GDIO1",
|
||||
"XTAL_32K_N",
|
||||
"LP_UART_DSRN",
|
||||
"ADC1_CH1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"Clock",
|
||||
"UART",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "GPIO2",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO2",
|
||||
"LP_GDIO2",
|
||||
"LP_UART_RTSN",
|
||||
"ADC1_CH2",
|
||||
"FSPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"ADC",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "GPIO3",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"LP_GDIO3",
|
||||
"LP_UART_CTSN",
|
||||
"ADC1_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "MTMS",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"LP_GDIO4",
|
||||
"LP_UART_RXD",
|
||||
"ADC1_CH3",
|
||||
"FSPIHD",
|
||||
"MTMS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Pino utilizado para debugging",
|
||||
"Utilizado para controlar a temporização do SDIO Slave (consulte o item 3.2 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "MTDI",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"LP_GDIO5",
|
||||
"LP_UART_TXD",
|
||||
"ADC1_CH5",
|
||||
"FSPIWP",
|
||||
"MTDI"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"UART",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Pino utilizado para debugging",
|
||||
"Utilizado para controlar a temporização do SDIO Slave (consulte o item 3.2 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "MTCK",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"LP_GDIO6",
|
||||
"LP_I2C_SDA",
|
||||
"ADC1_CH6",
|
||||
"FSPICLK",
|
||||
"MTCK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"I2C",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"A função de I2C_SDA está disponível no modo de baixo consumo (LP)",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "MTDO",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO7",
|
||||
"LP_GDIO7",
|
||||
"LP_I2C_SCL",
|
||||
"FSPID",
|
||||
"MTDO"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"I2C",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"A função de I2C_SDA está disponível no modo de baixo consumo (LP)",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": ["GPIO8"],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Utilizado para controlar o modo de boot do chip (consulte o item 3.1 do datasheet para mais detalhes)",
|
||||
"Utilizado para controlar a exibição de mensagens ROM na UART0 (consulte o item 3.3 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": ["GPIO9"],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado para controlar o modo de boot do chip (consulte o item 3.1 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": ["GPIO10"],
|
||||
"categorias": ["GPIO"],
|
||||
"avisos": ["Após o reset, este pino estará configurado como entrada"]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "GPIO11",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": ["GPIO11"],
|
||||
"categorias": ["GPIO"],
|
||||
"avisos": ["Após o reset, este pino estará configurado como entrada"]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "GPIO12",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"USB_D-"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Por padrão, este pino é utilizado para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "GPIO13",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"USB_D+"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Por padrão, este pino é utilizado para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "SPICS0",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": [
|
||||
"GPIO24",
|
||||
"SPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "SPIQ",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": [
|
||||
"GPIO25",
|
||||
"SPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "SPIWP",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": [
|
||||
"GPIO26",
|
||||
"SPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "VDD_SPI",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada/Saída de alimentação para a memória flash",
|
||||
"GPIO27"
|
||||
],
|
||||
"categorias": [
|
||||
"Power",
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip",
|
||||
"Só pode ser utilizado como GPIO se a memória flash externa estiver sendo alimentada por uma fonte externa"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "SPIHD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": [
|
||||
"GPIO28",
|
||||
"SPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "SPICLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": [
|
||||
"GPIO29",
|
||||
"SPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "SPID",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": [
|
||||
"GPIO30",
|
||||
"SPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado pela memória flash SPI",
|
||||
"Não é recomendado utilizar este pino como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "GPIO15",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": ["GPIO15"],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Utilizado para controlar a fonte de sinais JTAG (consulte o item 3.4 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "VDDA2",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio digital de alto desempenho"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "U0TXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO16",
|
||||
"U0TXD",
|
||||
"FSPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará com o pull-up interno ativado",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "U0RXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"U0RXD",
|
||||
"FSPICS1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "SDIO_CMD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO18",
|
||||
"SDIO_CMD",
|
||||
"FSPICS2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "SDIO_CLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO19",
|
||||
"SDIO_CLK",
|
||||
"FSPICS3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "SDIO_DATA0",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"SDIO_DATA0",
|
||||
"FSPICS4"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "34",
|
||||
"nome": "SDIO_DATA1",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO21",
|
||||
"SDIO_DATA1",
|
||||
"FSPICS5"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "35",
|
||||
"nome": "SDIO_DATA2",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO22",
|
||||
"SDIO_DATA2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "36",
|
||||
"nome": "SDIO_DATA3",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO23",
|
||||
"SDIO_DATA3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "37",
|
||||
"nome": "VDDA1",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "38",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Entrada/Saída negativa de clock"],
|
||||
"categorias": ["Clock"],
|
||||
"avisos": ["Consulte o item 2.4 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "39",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Entrada/Saída positiva de clock"],
|
||||
"categorias": ["Clock"],
|
||||
"avisos": ["Consulte o item 2.4 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "40",
|
||||
"nome": "VDDA2",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "41",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": ["Referência elétrica do circuito (terra)"],
|
||||
"categorias": ["GND"]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,536 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "ANT_2G",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Conexão de antena de RF (Wi-Fi e Bluetooth)"],
|
||||
"categorias": ["Antena", "RF"],
|
||||
"avisos": ["Pino de RF dedicado a 2.4 GHz. Requer casamento de impedância de 50 ohms."]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDDA3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação do domínio analógico de 3.3V"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Tensão recomendada: 3.3V (3.0V a 3.6V). Fornece energia para circuitos de RF e clock."]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDDA4",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação do domínio analógico de 3.3V"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Tensão recomendada: 3.3V (3.0V a 3.6V). Fornece energia para circuitos de RF e clock."]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "CHIP_PU",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Habilitar o chip (Power-up / Reset)"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Ativo Alto. Puxe para nível alto para inicializar o chip.",
|
||||
"Não deixe este pino flutuando. Recomenda-se usar um circuito RC externo para reset limpo."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação digital dos domínios HP (High Performance) e LP (Low Power)"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Tensão recomendada: 3.3V. Alimenta a parte digital de baixo consumo e pinos associados."]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "GPIO0",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"XTAL_32K_P"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock"
|
||||
],
|
||||
"avisos": ["Pino multifuncional de baixo consumo. Pode ser conectado ao cristal oscilador de 32 kHz externo (Entrada P)."]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "GPIO1",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"XTAL_32K_N",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino multifuncional. Conexão do cristal de 32 kHz externo (Saída N) e entrada analógica ADC1 Canal 0."]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "GPIO2",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": ["GPIO2"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "GPIO3",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"MTMS",
|
||||
"ADC1_CH1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"ADC",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Pino multifuncional: JTAG MTMS, ADC1 Canal 1 e pino de Strapping para controle de borda de clock do SDIO.",
|
||||
"Flutuante por padrão durante o reset."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "GPIO4",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"MTDI",
|
||||
"ADC1_CH2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"ADC",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Pino multifuncional: JTAG MTDI, ADC1 Canal 2 e pino de Strapping para controle de borda de clock do SDIO.",
|
||||
"Flutuante por padrão durante o reset."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "GPIO5",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"MTCK",
|
||||
"ADC1_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino multifuncional: JTAG MTCK e entrada analógica ADC1 Canal 3."]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "GPIO6",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"MTDO"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": ["Pino multifuncional JTAG MTDO."]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "GPIO25",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO25",
|
||||
"SDIO_CMD",
|
||||
"FSPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino multifuncional de alta velocidade: SDIO Comando ou SPI2 Chip Select 0."]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO26",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO26",
|
||||
"SDIO_CLK",
|
||||
"FSPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino multifuncional de alta velocidade: SDIO Clock ou SPI2 Clock."]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO27",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO27",
|
||||
"SDIO_DATA0",
|
||||
"FSPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino multifuncional de alta velocidade: SDIO Dados 0 ou SPI2 MOSI (FSPID)."]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO28",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO28",
|
||||
"SDIO_DATA1",
|
||||
"FSPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino de alta velocidade: SDIO Dados 1 ou SPI2 MISO (FSPIQ)."]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "GPIO22",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO22",
|
||||
"SDIO_DATA2",
|
||||
"FSPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino de alta velocidade: SDIO Dados 2 ou SPI2 Write Protect."]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "GPIO23",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO23",
|
||||
"SDIO_DATA3",
|
||||
"FSPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino de alta velocidade: SDIO Dados 3 ou SPI2 Hold."]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "GPIO14",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI", "VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO14",
|
||||
"SPICS1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino dedicado para Chip Select 1 da interface de memória SPI Flash/PSRAM."]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "GPIO15",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI", "VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO15",
|
||||
"SPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino dedicado para Chip Select 0 da interface de memória SPI Flash."]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "VDDPST2",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação do domínio digital HP (High Performance)"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Tensão recomendada: 3.3V (3.0V a 3.6V). Alimenta as interfaces digitais rápidas."]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "GPIO16",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI", "VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO16",
|
||||
"SPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino de dados Q (MISO) da interface de memória flash SPI."]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "GPIO17",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI", "VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"SPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino de proteção contra escrita (Write Protect) da interface de memória flash SPI."]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "VDD_SPI",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Tensão de saída LDO gerada a partir de VDDPST2 para alimentar a flash e PSRAM"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão de saída configurável via software de acordo com as especificações da flash interna/externa (normalmente 3.3V ou 1.8V).",
|
||||
"Não deve ser usado como fonte geral de energia de alta corrente."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GPIO19",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI", "VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO19",
|
||||
"SPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino de controle de Hold da interface de memória flash SPI."]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "GPIO20",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI", "VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"SPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino de sinal de clock da interface de memória flash SPI."]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "GPIO21",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI", "VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO21",
|
||||
"SPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino de dados D (MOSI) da interface de memória flash SPI."]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "GPIO12",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"USB_D-"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": ["Pino de sinal negativo do transceptor USB Serial/JTAG integrado."]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "GPIO13",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"USB_D+"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Pino de sinal positivo do transceptor USB Serial/JTAG integrado.",
|
||||
"Possui resistor de pull-up integrado ativado por padrão na inicialização do USB."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "GPIO24",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": ["GPIO24"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": ["GPIO8"],
|
||||
"categorias": ["GPIO", "Strapping"],
|
||||
"avisos": [
|
||||
"Pino de Strapping para seleção do modo de boot e controle de impressão das mensagens da ROM.",
|
||||
"Flutuante por padrão durante o reset. Nível alto (1) ativa a impressão do log de inicialização."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": ["GPIO9"],
|
||||
"categorias": ["GPIO", "Strapping"],
|
||||
"avisos": [
|
||||
"Pino de Strapping principal para seleção do modo de boot.",
|
||||
"Equipado com pull-up fraco integrado. Nível alto (1) no reset ativa SPI Boot (carrega do flash). Nível baixo (0) força o modo de Download."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"U0RXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": ["Recepção serial UART0 (Serial RX para gravação do firmware externa e depuração)."]
|
||||
},
|
||||
{
|
||||
"numero": "34",
|
||||
"nome": "GPIO11",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO11",
|
||||
"U0TXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": ["Transmissão serial UART0 (Serial TX para gravação do firmware externa e depuração)."]
|
||||
},
|
||||
{
|
||||
"numero": "35",
|
||||
"nome": "GPIO29",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": ["GPIO29"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "36",
|
||||
"nome": "GPIO7",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": ["GPIO7"],
|
||||
"categorias": ["GPIO", "Strapping"],
|
||||
"avisos": [
|
||||
"Pino de Strapping para seleção da fonte dos sinais JTAG (inicialização precoce).",
|
||||
"Sem resistores de pull internos no reset. Deve ser mantido estável por circuito externo se usado."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "37",
|
||||
"nome": "VDDA1",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação do domínio analógico de 3.3V"],
|
||||
"categorias": ["Power"]
|
||||
},
|
||||
{
|
||||
"numero": "38",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Conexão externa do cristal oscilador de 40 MHz (Saída N)"],
|
||||
"categorias": ["Clock"]
|
||||
},
|
||||
{
|
||||
"numero": "39",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Conexão externa do cristal oscilador de 40 MHz (Entrada P)"],
|
||||
"categorias": ["Clock"]
|
||||
},
|
||||
{
|
||||
"numero": "40",
|
||||
"nome": "VDDA2",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação do domínio analógico de 3.3V"],
|
||||
"categorias": ["Power"]
|
||||
},
|
||||
{
|
||||
"numero": "41",
|
||||
"nome": "GND",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Pino de aterramento central (Exposed Pad)"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Deve ser adequadamente soldado ao plano de terra (GND) da PCB para controle de RF e térmica estáveis."]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,482 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "GPIO0",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"FSPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "GPIO1",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"FSPICS0",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "MTMS",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"FSPIWP",
|
||||
"ADC1_CH1",
|
||||
"MTMS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"ADC",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "MTDO",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"FSPIHD",
|
||||
"ADC1_CH2",
|
||||
"MTDO"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"ADC",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "MTCK",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"FSPICLK",
|
||||
"ADC1_CH3",
|
||||
"MTCK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"ADC",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "MTDI",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"FSPID",
|
||||
"ADC1_CH4",
|
||||
"MTDI"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"ADC",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio das IOs"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": ["GPIO8"],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Utilizado para controlar o modo de boot do chip (consulte o item 3.1 do datasheet para mais detalhes)",
|
||||
"Utilizado para controlar a exibição de mensagens ROM na UART0 (consulte o item 3.3 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": ["GPIO9"],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado para controlar o modo de boot do chip (consulte o item 3.1 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"ZCD0"
|
||||
],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "GPIO11",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST1"],
|
||||
"funcoes": [
|
||||
"GPIO11",
|
||||
"ZCD1"
|
||||
],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO12",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDA_PMU", "VBAT"],
|
||||
"funcoes": ["GPIO12"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "XTAL_32K_P",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDA_PMU", "VBAT"],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"XTAL_32K_P"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "XTAL_32K_N",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDA_PMU", "VBAT"],
|
||||
"funcoes": [
|
||||
"GPIO14",
|
||||
"XTAL_32K_N"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "CHIP_EN",
|
||||
"tipo": "analog",
|
||||
"alimentacao": ["VBAT"],
|
||||
"funcoes": ["Habilitar o chip"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Colocar este pino em nível alto habilitará o funcionamento do chip",
|
||||
"Colocar este pino em nível baixo desabilitará o funcionamento do chip",
|
||||
"Não deixe este pino flutuando, utilize um resistor de pull-up externo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "VBAT",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico ou da bateria"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "VDDA_PMU",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio das IOs"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "GPIO22",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": ["GPIO22"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "U0RXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO23",
|
||||
"U0RXD",
|
||||
"FSPICS1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "U0TXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO24",
|
||||
"U0TXD",
|
||||
"FSPICS2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "GPIO25",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO24",
|
||||
"FSPICS3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada",
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Utilizado para controlar a fonte de sinais JTAG (consulte o item 3.3 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GPIO26",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO26",
|
||||
"FSPICS4",
|
||||
"USB_D-"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Por padrão, este pino é utilizado para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "GPIO27",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST2"],
|
||||
"funcoes": [
|
||||
"GPIO27",
|
||||
"FSPICS5",
|
||||
"USB_D+"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno para USB ativado",
|
||||
"Por padrão, este pino é utilizado para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Entrada/Saída negativa de clock"],
|
||||
"categorias": ["Clock"],
|
||||
"avisos": ["Consulte o item 2.3.2 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Entrada/Saída positiva de clock"],
|
||||
"categorias": ["Clock"],
|
||||
"avisos": ["Consulte o item 2.3.2 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "ANT",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Conexão da antena RF"],
|
||||
"categorias": ["Antena"],
|
||||
"avisos": ["Consulte o item 2.4 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": ["Referência elétrica do circuito (terra)"],
|
||||
"categorias": ["GND"]
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,956 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "ANT",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Conexão de antena de RF (Wi-Fi e Bluetooth)"],
|
||||
"categorias": ["Antena", "RF"],
|
||||
"avisos": ["Pino de RF dedicado para 2.4 GHz. Requer casamento de impedância de 50 ohms."]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDDA3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação do domínio analógico (3.3V)"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Tensão recomendada: 3.3V (3.0V a 3.6V). Alimenta a seção de RF e clock."]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDDA4",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação do domínio analógico (3.3V)"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Tensão recomendada: 3.3V (3.0V a 3.6V). Alimenta a seção de RF e clock."]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "CHIP_PU",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Habilitar o chip (Power-up / Reset)"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Ativo Alto. Puxe para nível alto para inicializar o chip.",
|
||||
"Não deixe este pino flutuando. Recomenda-se usar um circuito RC externo de atraso para inicialização estável."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "GPIO0",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"XTAL_32K_N"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock"
|
||||
],
|
||||
"avisos": ["Pino de clock de baixo consumo. Pode ser conectado ao cristal de 32.768 kHz externo (Pino N)."]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "GPIO1",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"XTAL_32K_P",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino multifuncional. Cristal de 32.768 kHz externo (Pino P) e entrada analógica ADC1 Canal 0."]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "GPIO2",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO2",
|
||||
"ADC1_CH1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC1 Canal 1."]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "GPIO3",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"ADC1_CH2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC1 Canal 2."]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "GPIO4",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"ADC1_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC1 Canal 3."]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "GPIO5",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"ADC1_CH4"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC1 Canal 4."]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "VDDPST_1",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação de I/O do domínio 1 (3.3V)"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Tensão recomendada: 3.3V."]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "GPIO6",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"ADC1_CH5"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC1 Canal 5."]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "GPIO7",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO7",
|
||||
"ADC1_CH6"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC1 Canal 6."]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO8",
|
||||
"ADC1_CH7"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC1 Canal 7."]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO9",
|
||||
"ADC1_CH8"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC1 Canal 8."]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"ADC1_CH9"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC1 Canal 9."]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "GPIO11",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO11",
|
||||
"ADC1_CH10"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC1 Canal 10."]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "VREF_TOUCH",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Tensão de referência para os pinos Touch capacitivos"],
|
||||
"categorias": ["Touch"],
|
||||
"avisos": ["Pino analógico dedicado para estabilização de leitura capacitiva."]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "GPIO12",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"ADC2_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC2 Canal 0."]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "GPIO13",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"ADC2_CH1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC2 Canal 1."]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "GPIO14",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO14",
|
||||
"ADC2_CH2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC2 Canal 2."]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "GPIO15",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO15",
|
||||
"ADC2_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC2 Canal 3."]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "GPIO16",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO16",
|
||||
"ADC2_CH4"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC2 Canal 4."]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "GPIO17",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"ADC2_CH5"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC2 Canal 5."]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GPIO18",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO18",
|
||||
"ADC2_CH6"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC2 Canal 6."]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "GPIO19",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_1"],
|
||||
"funcoes": [
|
||||
"GPIO19",
|
||||
"ADC2_CH7"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino de entrada analógica ADC2 Canal 7."]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "SDIO_DATA0",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_SD"],
|
||||
"funcoes": [
|
||||
"SDIO_DATA0",
|
||||
"FSPID"
|
||||
],
|
||||
"categorias": [
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino da interface SDIO de alta velocidade (Dados 0) ou SPI2 MOSI."]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "SDIO_DATA1",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_SD"],
|
||||
"funcoes": [
|
||||
"SDIO_DATA1",
|
||||
"FSPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino da interface SDIO de alta velocidade (Dados 1) ou SPI2 MISO."]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "SDIO_DATA2",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_SD"],
|
||||
"funcoes": [
|
||||
"SDIO_DATA2",
|
||||
"FSPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino da interface SDIO de alta velocidade (Dados 2) ou SPI2 Write Protect."]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "VDD_PSRAM_1P8_1",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação de 1.8V para PSRAM integrada no encapsulamento"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Gerado pelo LDO interno para alimentar a PSRAM integrada. Não conectar a circuitos de potência externa."]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "SDIO_DATA3",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_SD"],
|
||||
"funcoes": [
|
||||
"SDIO_DATA3",
|
||||
"FSPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Pino da interface SDIO de alta velocidade (Dados 3) ou SPI2 Hold."]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "SDIO_CLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_SD"],
|
||||
"funcoes": [
|
||||
"SDIO_CLK",
|
||||
"FSPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Clock da interface SDIO de alta velocidade ou SPI2 Clock."]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "SDIO_CMD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_SD"],
|
||||
"funcoes": [
|
||||
"SDIO_CMD",
|
||||
"FSPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Comando da interface SDIO de alta velocidade ou SPI2 Chip Select 0."]
|
||||
},
|
||||
{
|
||||
"numero": "34",
|
||||
"nome": "VDD_PSRAM_1P8_2",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação de 1.8V para PSRAM integrada no encapsulamento"],
|
||||
"categorias": ["Power"]
|
||||
},
|
||||
{
|
||||
"numero": "35",
|
||||
"nome": "VDD_LDO_1P8",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Pino de entrada/saída LDO de 1.8V"],
|
||||
"categorias": ["Power"]
|
||||
},
|
||||
{
|
||||
"numero": "36",
|
||||
"nome": "SPICS",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": ["SPICS"],
|
||||
"categorias": ["SPI"],
|
||||
"avisos": ["Chip Select dedicado para a Flash SPI externa ou interna."]
|
||||
},
|
||||
{
|
||||
"numero": "37",
|
||||
"nome": "SPIQ",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": ["SPIQ"],
|
||||
"categorias": ["SPI"],
|
||||
"avisos": ["Dado Q (MISO) dedicado para a Flash SPI externa ou interna."]
|
||||
},
|
||||
{
|
||||
"numero": "38",
|
||||
"nome": "SPIWP",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": ["SPIWP"],
|
||||
"categorias": ["SPI"],
|
||||
"avisos": ["Write Protect dedicado para a Flash SPI externa ou interna."]
|
||||
},
|
||||
{
|
||||
"numero": "39",
|
||||
"nome": "VDD_SPI",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Tensão de alimentação dedicada para a interface Flash SPI"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Tensão típica: 3.3V ou 1.8V gerada internamente."]
|
||||
},
|
||||
{
|
||||
"numero": "40",
|
||||
"nome": "SPIHD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": ["SPIHD"],
|
||||
"categorias": ["SPI"],
|
||||
"avisos": ["Hold dedicado para a Flash SPI externa ou interna."]
|
||||
},
|
||||
{
|
||||
"numero": "41",
|
||||
"nome": "SPICLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": ["SPICLK"],
|
||||
"categorias": ["SPI"],
|
||||
"avisos": ["Clock dedicado para a Flash SPI externa ou interna."]
|
||||
},
|
||||
{
|
||||
"numero": "42",
|
||||
"nome": "SPID",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SPI"],
|
||||
"funcoes": ["SPID"],
|
||||
"categorias": ["SPI"],
|
||||
"avisos": ["Dado D (MOSI) dedicado para a Flash SPI externa ou interna."]
|
||||
},
|
||||
{
|
||||
"numero": "43",
|
||||
"nome": "VCCA/VDDPST_2",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação analógica e digital do domínio 2 (3.3V)"],
|
||||
"categorias": ["Power"]
|
||||
},
|
||||
{
|
||||
"numero": "44",
|
||||
"nome": "USB_DP",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Pino positivo do transceptor USB Serial/JTAG integrado"],
|
||||
"categorias": ["USB"],
|
||||
"avisos": ["USB D+. Possui pull-up de hardware interno."]
|
||||
},
|
||||
{
|
||||
"numero": "45",
|
||||
"nome": "USB_DM",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Pino negativo do transceptor USB Serial/JTAG integrado"],
|
||||
"categorias": ["USB"],
|
||||
"avisos": ["USB D-."]
|
||||
},
|
||||
{
|
||||
"numero": "46",
|
||||
"nome": "GPIO33",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO33",
|
||||
"ADC2_CH8"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino multifuncional: GPIO33 e ADC2 Canal 8."]
|
||||
},
|
||||
{
|
||||
"numero": "47",
|
||||
"nome": "GPIO34",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO34",
|
||||
"ADC2_CH9"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Pino multifuncional: GPIO34 e ADC2 Canal 9."]
|
||||
},
|
||||
{
|
||||
"numero": "48",
|
||||
"nome": "GPIO35",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO35",
|
||||
"ADC2_CH10"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "49",
|
||||
"nome": "GPIO36",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO36",
|
||||
"ADC2_CH11"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "50",
|
||||
"nome": "GPIO37",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO37",
|
||||
"ADC2_CH12"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "51",
|
||||
"nome": "GPIO38",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO38",
|
||||
"ADC2_CH13"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "52",
|
||||
"nome": "GPIO39",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO39",
|
||||
"ADC2_CH14"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "53",
|
||||
"nome": "GPIO40",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO40",
|
||||
"ADC2_CH15"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "54",
|
||||
"nome": "VDDPST_3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação de I/O do domínio 3 (3.3V)"],
|
||||
"categorias": ["Power"]
|
||||
},
|
||||
{
|
||||
"numero": "55",
|
||||
"nome": "GPIO42",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO42",
|
||||
"ADC2_CH16"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "56",
|
||||
"nome": "GPIO43",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO43",
|
||||
"ADC2_CH17"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "57",
|
||||
"nome": "GPIO44",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO44",
|
||||
"ADC2_CH18"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "58",
|
||||
"nome": "GPIO45",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO45",
|
||||
"ADC2_CH19"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "59",
|
||||
"nome": "GPIO46",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO46",
|
||||
"ADC2_CH20"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "60",
|
||||
"nome": "GPIO47",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": [
|
||||
"GPIO47",
|
||||
"ADC2_CH21"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "61",
|
||||
"nome": "GPIO48",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": ["GPIO48"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "62",
|
||||
"nome": "GPIO49",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_3"],
|
||||
"funcoes": ["GPIO49"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "63",
|
||||
"nome": "VREF_ADC",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Tensão de referência estável externa para calibração do ADC"],
|
||||
"categorias": ["Power", "ADC"],
|
||||
"avisos": ["Pino analógico dedicado para calibração precisa do conversor analógico-digital."]
|
||||
},
|
||||
{
|
||||
"numero": "64",
|
||||
"nome": "VDDPST_4",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação de I/O do domínio 4 (3.3V)"],
|
||||
"categorias": ["Power"]
|
||||
},
|
||||
{
|
||||
"numero": "65",
|
||||
"nome": "GPIO50",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_4"],
|
||||
"funcoes": ["GPIO50"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "66",
|
||||
"nome": "GPIO51",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_4"],
|
||||
"funcoes": ["GPIO51"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "67",
|
||||
"nome": "GPIO52",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_4"],
|
||||
"funcoes": ["GPIO52"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "68",
|
||||
"nome": "GPIO53",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_4"],
|
||||
"funcoes": ["GPIO53"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "69",
|
||||
"nome": "GPIO54",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_4"],
|
||||
"funcoes": [
|
||||
"GPIO54",
|
||||
"MTDO"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": ["Pino multifuncional: JTAG MTDO."]
|
||||
},
|
||||
{
|
||||
"numero": "70",
|
||||
"nome": "GPIO55",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_4"],
|
||||
"funcoes": [
|
||||
"GPIO55",
|
||||
"MTCK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": ["Pino multifuncional: JTAG MTCK."]
|
||||
},
|
||||
{
|
||||
"numero": "71",
|
||||
"nome": "GPIO56",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_4"],
|
||||
"funcoes": [
|
||||
"GPIO56",
|
||||
"MTDI"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": ["Pino multifuncional: JTAG MTDI."]
|
||||
},
|
||||
{
|
||||
"numero": "72",
|
||||
"nome": "GPIO57",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_4"],
|
||||
"funcoes": [
|
||||
"GPIO57",
|
||||
"MTMS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": ["Pino multifuncional: JTAG MTMS."]
|
||||
},
|
||||
{
|
||||
"numero": "73",
|
||||
"nome": "GPIO58",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_4"],
|
||||
"funcoes": ["GPIO58"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "74",
|
||||
"nome": "GPIO59",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_4"],
|
||||
"funcoes": ["GPIO59"],
|
||||
"categorias": ["GPIO"]
|
||||
},
|
||||
{
|
||||
"numero": "75",
|
||||
"nome": "GPIO60",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_4"],
|
||||
"funcoes": ["GPIO60"],
|
||||
"categorias": ["GPIO", "Strapping"],
|
||||
"avisos": [
|
||||
"Pino de Strapping para boot (junto com GPIO61).",
|
||||
"Equipado com pull-up interno ativo por padrão."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "76",
|
||||
"nome": "GPIO61",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDDPST_4"],
|
||||
"funcoes": ["GPIO61"],
|
||||
"categorias": ["GPIO", "Strapping"],
|
||||
"avisos": [
|
||||
"Pino de Strapping principal para seleção de boot.",
|
||||
"Equipado com pull-up interno ativo por padrão. Nível alto (1) no reset ativa SPI Boot. Nível baixo (0) força o modo Download."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "77",
|
||||
"nome": "VDDA1",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação do domínio analógico de 3.3V"],
|
||||
"categorias": ["Power"]
|
||||
},
|
||||
{
|
||||
"numero": "78",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Conexão externa do cristal oscilador de alta velocidade (Saída N)"],
|
||||
"categorias": ["Clock"]
|
||||
},
|
||||
{
|
||||
"numero": "79",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": ["Conexão externa do cristal oscilador de alta velocidade (Entrada P)"],
|
||||
"categorias": ["Clock"]
|
||||
},
|
||||
{
|
||||
"numero": "80",
|
||||
"nome": "VDDA2",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Alimentação do domínio analógico de 3.3V"],
|
||||
"categorias": ["Power"]
|
||||
},
|
||||
{
|
||||
"numero": "81",
|
||||
"nome": "GND",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Pino de aterramento central (Exposed Pad)"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": ["Deve ser adequadamente soldado ao plano de terra (GND) da PCB para controle de RF e dissipação térmica estáveis."]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,964 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 2.3V ou 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Para chips com a flash ou PSRAM integrada, a tensão mínima recomendada é 3.0V",
|
||||
"Para chips sem a flash ou PSRAM integrada, a tensão mínima recomendada é 2.3V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "LNA_IN",
|
||||
"tipo": "analog",
|
||||
"alimentação": ["VDD3P3"],
|
||||
"funcoes": ["Entrada do amplificador de baixo ruído (LNA) para o receptor Wi-Fi e Bluetooth"],
|
||||
"categorias": ["Antena"],
|
||||
"avisos": ["Consulte o item 2.4 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 2.3V ou 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Para chips com a flash ou PSRAM integrada, a tensão mínima recomendada é 3.0V",
|
||||
"Para chips sem a flash ou PSRAM integrada, a tensão mínima recomendada é 2.3V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 2.3V ou 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Para chips com a flash ou PSRAM integrada, a tensão mínima recomendada é 3.0V",
|
||||
"Para chips sem a flash ou PSRAM integrada, a tensão mínima recomendada é 2.3V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "SENSOR_VP",
|
||||
"tipo": "analog",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO36",
|
||||
"RTC_GPIO0",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Este pino é de apenas de entrada (input only)"]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "SENSOR_CAPP",
|
||||
"tipo": "analog",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO37",
|
||||
"RTC_GPIO1",
|
||||
"ADC1_CH1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Este pino é de apenas de entrada (input only)"]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "SENSOR_CAPN",
|
||||
"tipo": "analog",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO38",
|
||||
"RTC_GPIO2",
|
||||
"ADC1_CH2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Este pino é de apenas de entrada (input only)"]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "SENSOR_VN",
|
||||
"tipo": "analog",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO39",
|
||||
"RTC_GPIO3",
|
||||
"ADC1_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Este pino é de apenas de entrada (input only)"]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "CHIP_PU",
|
||||
"tipo": "analog",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": ["Habilitar o chip"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Colocar este pino em nível alto habilitará o funcionamento do chip",
|
||||
"Colocar este pino em nível baixo desabilitará o funcionamento do chip",
|
||||
"Não deixe este pino flutuando, utilize um resistor de pull-up externo",
|
||||
"Consulte o item 2.4 do datasheet para mais detalhes sobre pinos analógicos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "VDET_1",
|
||||
"tipo": "analog",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO34",
|
||||
"RTC_GPIO4",
|
||||
"ADC1_CH6"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Este pino é de apenas de entrada (input only)"]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "VDET_2",
|
||||
"tipo": "analog",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO35",
|
||||
"RTC_GPIO5",
|
||||
"ADC1_CH7"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": ["Este pino é de apenas de entrada (input only)"]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "32K_XP",
|
||||
"tipo": "analog",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO32",
|
||||
"RTC_GPIO9",
|
||||
"ADC1_CH4",
|
||||
"TOUCH9",
|
||||
"XTAL_32K_P"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"Touch",
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "32K_XN",
|
||||
"tipo": "analog",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO33",
|
||||
"RTC_GPIO8",
|
||||
"ADC1_CH5",
|
||||
"TOUCH8",
|
||||
"XTAL_32K_N"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"Touch",
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO25",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO25",
|
||||
"RTC_GPIO6",
|
||||
"ADC2_CH8",
|
||||
"DAC_1",
|
||||
"EMAC_RXD0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"DAC",
|
||||
"Ethernet"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO26",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO26",
|
||||
"RTC_GPIO7",
|
||||
"ADC2_CH9",
|
||||
"DAC_2",
|
||||
"EMAC_RXD1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"DAC",
|
||||
"Ethernet"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO27",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO27",
|
||||
"RTC_GPIO17",
|
||||
"ADC2_CH7",
|
||||
"TOUCH7",
|
||||
"EMAC_RXDV"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"Touch",
|
||||
"Ethernet"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "MTMS",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO14",
|
||||
"RTC_GPIO16",
|
||||
"ADC2_CH6",
|
||||
"TOUCH6",
|
||||
"HSPICLK",
|
||||
"HS2_CLK",
|
||||
"SD_CLK",
|
||||
"EMAC_TXD2",
|
||||
"MTMS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"Touch",
|
||||
"SPI",
|
||||
"SD",
|
||||
"Ethernet",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "MTDI",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"RTC_GPIO15",
|
||||
"ADC2_CH5",
|
||||
"TOUCH5",
|
||||
"HSPIQ",
|
||||
"HS2_DATA2",
|
||||
"SD_DATA2",
|
||||
"EMAC_TXD3",
|
||||
"MTDI"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"Touch",
|
||||
"SPI",
|
||||
"SD",
|
||||
"Ethernet",
|
||||
"JTAG",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-down interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-down interno ativado",
|
||||
"Pino utilizado para debugging",
|
||||
"Utilizado para controlar a tensão de VDD_SDIO (LDO interno) (consulte o item 3.2 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "VDD3P3_RTC",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio de baixo consumo (RTC) e parte do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 2.3V ou 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Para chips com a flash ou PSRAM integrada, a tensão mínima recomendada é 3.0V",
|
||||
"Para chips sem a flash ou PSRAM integrada, a tensão mínima recomendada é 2.3V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "MTCK",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"RTC_GPIO14",
|
||||
"ADC2_CH4",
|
||||
"TOUCH4",
|
||||
"HSPID",
|
||||
"HS2_DATA3",
|
||||
"SD_DATA3",
|
||||
"EMAC_RX_ER",
|
||||
"MTCK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"Touch",
|
||||
"SPI",
|
||||
"SD",
|
||||
"Ethernet",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-down interno ativado",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "MTDO",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO15",
|
||||
"RTC_GPIO13",
|
||||
"ADC2_CH3",
|
||||
"TOUCH3",
|
||||
"HSPICS0",
|
||||
"HS2_CMD",
|
||||
"SD_CMD",
|
||||
"EMAC_RXD3",
|
||||
"MTDO",
|
||||
"I2C_SDA"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"Touch",
|
||||
"SPI",
|
||||
"SD",
|
||||
"Ethernet",
|
||||
"JTAG",
|
||||
"I2C",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"A função de I2C_SDA está disponível no modo de baixo consumo (RTC)",
|
||||
"Pino utilizado para debugging",
|
||||
"Utilizado para controlar a exibição de mensagens ROM na UART0 (consulte o item 3.3 do datasheet para mais detalhes)",
|
||||
"Utilizado para controlar a temporização do SDIO Slave (consulte o item 3.4 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "GPIO2",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO2",
|
||||
"RTC_GPIO12",
|
||||
"ADC2_CH2",
|
||||
"TOUCH2",
|
||||
"HSPIWP",
|
||||
"HS2_DATA0",
|
||||
"SD_DATA0",
|
||||
"I2C_SCL"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"Touch",
|
||||
"SPI",
|
||||
"SD",
|
||||
"I2C",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-down interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-down interno ativado",
|
||||
"A função de I2C_SCL está disponível no modo de baixo consumo (RTC)",
|
||||
"Utilizado para controlar o modo de boot do chip (consulte o item 3.1 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "GPIO0",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"RTC_GPIO11",
|
||||
"ADC2_CH1",
|
||||
"TOUCH1",
|
||||
"CLC_OUT1",
|
||||
"EMAC_TX_CLK",
|
||||
"I2C_SDA"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"Touch",
|
||||
"Clock",
|
||||
"Ethernet",
|
||||
"I2C",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"A função de I2C_SDA está disponível no modo de baixo consumo (RTC)",
|
||||
"Utilizado para controlar o modo de boot do chip (consulte o item 3.1 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "GPIO4",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_RTC"],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"RTC_GPIO10",
|
||||
"ADC2_CH0",
|
||||
"TOUCH0",
|
||||
"HSPIHD",
|
||||
"HS2_DATA1",
|
||||
"SD_DATA1",
|
||||
"EMAC_TX_ER",
|
||||
"I2C_SCL"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"Touch",
|
||||
"SPI",
|
||||
"SD",
|
||||
"Ethernet",
|
||||
"I2C"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-down interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-down interno ativado",
|
||||
"A função de I2C_SCL está disponível no modo de baixo consumo (RTC)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GPIO16",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SDIO"],
|
||||
"funcoes": [
|
||||
"GPIO16",
|
||||
"HS1_DATA4",
|
||||
"U2RXD",
|
||||
"EMAC_CLK_OUT"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"UART",
|
||||
"Ethernet"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Dedicado a comunicação com a Flash/PSRAM interna, não recomendado para outras funções"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "VDD_SDIO",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada/saída da alimentação das memórias SDIO internas (Flash/PSRAM)"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 2.3V ou 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Este pino é conectado a saída do LDO interno",
|
||||
"Se for conectado diretamente ao VDD3P3_RTC, o LDO interno será desabilitado automaticamente",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "GPIO17",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SDIO"],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"HS1_DATA5",
|
||||
"U2TXD",
|
||||
"EMAC_CLK_OUT_180"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"UART",
|
||||
"Ethernet"
|
||||
],
|
||||
"avisos": [
|
||||
"Após o reset, este pino estará configurado como entrada",
|
||||
"Dedicado a comunicação com a Flash/PSRAM interna, não recomendado para outras funções"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "SD_DATA_2",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SDIO"],
|
||||
"funcoes": [
|
||||
"GPIO9",
|
||||
"SPIHD",
|
||||
"HS1_DATA2",
|
||||
"SD_DATA2",
|
||||
"U1RXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"SD",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Dedicado a comunicação com a Flash/PSRAM interna, não recomendado para outras funções"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "SD_DATA_3",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SDIO"],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"SPIWP",
|
||||
"HS1_DATA3",
|
||||
"SD_DATA3",
|
||||
"U1TXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"SD",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Dedicado a comunicação com a Flash/PSRAM interna, não recomendado para outras funções"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "SD_CMD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SDIO"],
|
||||
"funcoes": [
|
||||
"GPIO11",
|
||||
"SPICS0",
|
||||
"HS1_CMD",
|
||||
"SD_CMD",
|
||||
"U1RTS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"SD",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Dedicado a comunicação com a Flash/PSRAM interna, não recomendado para outras funções"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "SD_CLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SDIO"],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"SPICLK",
|
||||
"HS1_CLK",
|
||||
"SD_CLK",
|
||||
"U1CTS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"SD",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Dedicado a comunicação com a Flash/PSRAM interna, não recomendado para outras funções"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "SD_DATA_0",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SDIO"],
|
||||
"funcoes": [
|
||||
"GPIO7",
|
||||
"SPIQ",
|
||||
"HS1_DATA0",
|
||||
"SD_DATA0",
|
||||
"U2RTS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"SD",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Dedicado a comunicação com a Flash/PSRAM interna, não recomendado para outras funções"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "SD_DATA_1",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD_SDIO"],
|
||||
"funcoes": [
|
||||
"GPIO8",
|
||||
"SPID",
|
||||
"HS1_DATA1",
|
||||
"SD_DATA1",
|
||||
"U2CTS"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"SD",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Dedicado a comunicação com a Flash/PSRAM interna, não recomendado para outras funções"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "34",
|
||||
"nome": "GPIO5",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"VSPICS0",
|
||||
"HS1_DATA6",
|
||||
"EMAC_RX_CLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"Ethernet"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Utilizado para controlar a temporização do SDIO Slave (consulte o item 3.4 do datasheet para mais detalhes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "35",
|
||||
"nome": "GPIO18",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO18",
|
||||
"VSPICLK",
|
||||
"HS1_DATA7"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Após o reset, este pino estará configurado como entrada"]
|
||||
},
|
||||
{
|
||||
"numero": "36",
|
||||
"nome": "GPIO23",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO23",
|
||||
"VSPID",
|
||||
"HS1_STROBE"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": ["Após o reset, este pino estará configurado como entrada"]
|
||||
},
|
||||
{
|
||||
"numero": "37",
|
||||
"nome": "VDD3P3_CPU",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio digital"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 1.8V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "38",
|
||||
"nome": "GPIO19",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO19",
|
||||
"VSPIQ",
|
||||
"U0CTS",
|
||||
"EMAC_TXD0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"UART",
|
||||
"Ethernet"
|
||||
],
|
||||
"avisos": ["Após o reset, este pino estará configurado como entrada"]
|
||||
},
|
||||
{
|
||||
"numero": "39",
|
||||
"nome": "GPIO22",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO22",
|
||||
"VSPIWP",
|
||||
"U0RTS",
|
||||
"EMAC_TXD1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"UART",
|
||||
"Ethernet"
|
||||
],
|
||||
"avisos": ["Após o reset, este pino estará configurado como entrada"]
|
||||
},
|
||||
{
|
||||
"numero": "40",
|
||||
"nome": "U0RXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"CLK_OUT2",
|
||||
"U0RXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "41",
|
||||
"nome": "U0TXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"CLK_OUT3",
|
||||
"U0TXD",
|
||||
"EMAC_RXD2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Clock",
|
||||
"UART",
|
||||
"Ethernet"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Após o reset, este pino estará configurado como entrada com o pull-up interno ativado",
|
||||
"Pino utilizado para debugging"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "42",
|
||||
"nome": "GPIO21",
|
||||
"tipo": "io",
|
||||
"alimentacao": ["VDD3P3_CPU"],
|
||||
"funcoes": [
|
||||
"GPIO21",
|
||||
"VSPIHD",
|
||||
"EMAC_TX_EN"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"Ethernet"
|
||||
],
|
||||
"avisos": ["Após o reset, este pino estará configurado como entrada"]
|
||||
},
|
||||
{
|
||||
"numero": "43",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 2.3V ou 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Para chips com a flash ou PSRAM integrada, a tensão mínima recomendada é 3.0V",
|
||||
"Para chips sem a flash ou PSRAM integrada, a tensão mínima recomendada é 2.3V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "44",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"alimentação": ["VDDA"],
|
||||
"funcoes": ["Entrada/Saída negativa de clock"],
|
||||
"categorias": ["clock"],
|
||||
"avisos": ["Consulte o item 2.4 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "45",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"alimentação": ["VDDA"],
|
||||
"funcoes": ["Entrada/Saída positiva de clock"],
|
||||
"categorias": ["clock"],
|
||||
"avisos": ["Consulte o item 2.4 do datasheet para mais detalhes sobre pinos analógicos"]
|
||||
},
|
||||
{
|
||||
"numero": "46",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": ["Entrada de alimentação do domínio analógico"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Tensão Recomendada: 3.3V",
|
||||
"Tensão Mínima Recomendada: 2.3V ou 3.0V",
|
||||
"Tensão Máxima Recomendada: 3.6V",
|
||||
"Para chips com a flash ou PSRAM integrada, a tensão mínima recomendada é 3.0V",
|
||||
"Para chips sem a flash ou PSRAM integrada, a tensão mínima recomendada é 2.3V",
|
||||
"Consulte o item 2.5 do datasheet para mais detalhes sobre a alimentação do chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "47",
|
||||
"nome": "CAP2",
|
||||
"tipo": "analog",
|
||||
"alimentação": ["VDDA"],
|
||||
"funcoes": ["Capacitor de filtro"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Conecte um capacitor de 3.3nF (10%) e um resistor de 20kΩ em paralelo com o CAP1",
|
||||
"Consulte o item 2.2 do datasheet para mais detalhes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "48",
|
||||
"nome": "CAP1",
|
||||
"tipo": "analog",
|
||||
"alimentação": ["VDDA"],
|
||||
"funcoes": ["Capacitor de filtro"],
|
||||
"categorias": ["Power"],
|
||||
"avisos": [
|
||||
"Conecte um capacitor de 10nF em série com o GND",
|
||||
"Consulte o item 2.2 do datasheet para mais detalhes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "49",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": ["Referência elétrica do circuito (terra)"],
|
||||
"categorias": ["GND"]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,394 @@
|
||||
{
|
||||
"ESP-IDF": {
|
||||
"nome": "ESP-IDF",
|
||||
"icone": "⚙️",
|
||||
"nome_completo": "Espressif IoT Development Framework",
|
||||
"descricao": "Framework oficial nativo da Espressif para todos os SoCs ESP32. Baseado em FreeRTOS multicore e CMake, oferece controle total do silício, periféricos, rádio e arquitetura de componentes modulares.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Framework Base Oficial",
|
||||
"funcao_principal": "Desenvolvimento industrial e de alta performance com acesso direto aos registradores, RTOS em tempo real e pilha completa de protocolos",
|
||||
"caracteristicas": [
|
||||
"Sistema operacional de tempo real (FreeRTOS SMP multicore)",
|
||||
"Suporte nativo ao ESP Component Registry via idf_component.yml",
|
||||
"Pilha completa de conectividade Wi-Fi 4/6, BLE 5.x, Zigbee e Thread",
|
||||
"Suporte a todos os SoCs (ESP32, S2, S3, C2, C3, C6, H2, P4)",
|
||||
"Gerenciamento avançado de energia e modos Deep Sleep",
|
||||
"Segurança robusta: Secure Boot v2, Flash Encryption e Crypto HW",
|
||||
"Atualizações OTA criptografadas com rollback automático",
|
||||
"Toolchain moderna Clang/GCC, suporte a C++23 e debug via JTAG OpenOCD"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Produtos comerciais e industriais de IoT",
|
||||
"Dispositivos com requisitos rigorosos de bateria e consumo",
|
||||
"Aplicações em tempo real com controle de interrupções",
|
||||
"Sistemas de segurança com criptografia de hardware",
|
||||
"Gateways multiprotocolo de alto desempenho"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-idf.c",
|
||||
"exemplos": "https://github.com/espressif/esp-idf/tree/master/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-idf/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-idf",
|
||||
"cor": "#E74C3C"
|
||||
},
|
||||
"ESP-RainMaker": {
|
||||
"nome": "ESP-RainMaker",
|
||||
"icone": "☁️",
|
||||
"nome_completo": "ESP RainMaker AIoT Cloud Platform",
|
||||
"descricao": "Plataforma completa de nuvem e firmware da Espressif para produtos conectados. Permite criar dispositivos IoT sem precisar desenvolver backend ou aplicativos móveis do zero.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Cloud & AIoT Framework",
|
||||
"funcao_principal": "Construção acelerada de produtos inteligentes com aplicativo móvel (iOS/Android), nuvem AWS Serverless e controle por voz (Alexa/Google Home)",
|
||||
"caracteristicas": [
|
||||
"Provisionamento Wi-Fi e BLE assistido via aplicativo oficial",
|
||||
"Geração dinâmica de interface no app com base nos parâmetros do firmware",
|
||||
"Integração nativa com Amazon Alexa e Google Assistant",
|
||||
"Suporte a controle local (Local Control via mDNS/HTTP) e nuvem simultâneos",
|
||||
"Painel administrativo (RainMaker Dashboard) para gerenciamento de frotas e OTA",
|
||||
"Compatibilidade nativa com nós Matter e Bridge de dispositivos",
|
||||
"Biblioteca integrada via ESP Component Registry (espressif/esp_rainmaker)"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Eletrodomésticos e iluminação inteligente para consumidor final",
|
||||
"Produtos IoT com prazo reduzido de lançamento no mercado (Time-to-Market)",
|
||||
"Dispositivos que exigem controle por app móvel sem custo de infraestrutura própria",
|
||||
"Sistemas de monitoramento remoto com atualização OTA centralizada"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-rainmaker.c",
|
||||
"exemplos": "https://github.com/espressif/esp-rainmaker/tree/master/examples",
|
||||
"documentacao": "https://rainmaker.espressif.com/docs/",
|
||||
"repositorio": "https://github.com/espressif/esp-rainmaker",
|
||||
"cor": "#3B82F6"
|
||||
},
|
||||
"ESP-Matter": {
|
||||
"nome": "ESP-Matter",
|
||||
"icone": "🏠",
|
||||
"nome_completo": "ESP Matter SDK",
|
||||
"descricao": "SDK oficial da Espressif para o padrão universal de casa inteligente Matter (antigo Project CHIP). Permite que seus dispositivos operem de forma interoperável com Apple HomeKit, Google Home, Amazon Alexa e Home Assistant.",
|
||||
"linguagem": "C++",
|
||||
"tipo": "Smart Home Framework",
|
||||
"funcao_principal": "Desenvolvimento de dispositivos e pontes inteligentes compatíveis com o padrão unificado Matter sobre Wi-Fi e Thread",
|
||||
"caracteristicas": [
|
||||
"Implementação completa dos clusters da especificação Matter",
|
||||
"Suporte a transporte sobre Wi-Fi e Thread (802.15.4 em ESP32-H2 e ESP32-C6)",
|
||||
"Comissionamento simplificado via BLE ou On-Network",
|
||||
"Compatibilidade simultânea com Apple Home, Google Home, Alexa e SmartThings",
|
||||
"Segurança baseada em certificados de autenticação de dispositivo (DAC)",
|
||||
"Suporte a Matter Bridge (conectando dispositivos legados Zigbee/BLE ao Matter)",
|
||||
"Integração direta ao ESP-IDF e ESP Component Registry"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Lâmpadas, tomadas, interruptores e dimmers interoperáveis",
|
||||
"Sensores de presença, temperatura, umidade e contato",
|
||||
"Fechaduras eletrônicas e atuadores de cortinas",
|
||||
"Matter Border Routers e Bridges residenciais"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-matter.c",
|
||||
"exemplos": "https://github.com/espressif/esp-matter/tree/main/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-matter/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-matter",
|
||||
"cor": "#F59E0B"
|
||||
},
|
||||
"ESP-ADF": {
|
||||
"nome": "ESP-ADF",
|
||||
"icone": "🎵",
|
||||
"nome_completo": "ESP Audio Development Framework",
|
||||
"descricao": "Framework especializado para processamento, streaming e reprodução de áudio digital de alta qualidade em SoCs ESP32.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Framework de Áudio & Voz",
|
||||
"funcao_principal": "Criação de pipelines de áudio flexíveis com decodificadores, streaming de rede, equalização e efeitos acústicos",
|
||||
"caracteristicas": [
|
||||
"Arquitetura de pipeline de áudio modular (Audio Elements & Audio Stream)",
|
||||
"Suporte a múltiplos codecs: MP3, AAC, FLAC, WAV, OGG, Opus e AMR",
|
||||
"Streaming de áudio via HTTP, HTTPS, HLS, RTSP e WebSockets",
|
||||
"Suporte a Bluetooth A2DP (Sink/Source) e Bluetooth Handsfree (HFP)",
|
||||
"Algoritmos de processamento acústico (AEC, AGC, NS, equalizadores paramétricos)",
|
||||
"Suporte a placas dedicadas como ESP32-LyraT e ESP32-S3-Korvo"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Caixas de som inteligentes e internet radios",
|
||||
"Intercomunicadores, walkie-talkies e sistemas de interfonia VoIP",
|
||||
"Aparelhos de reprodução musical com PSRAM",
|
||||
"Sistemas de som ambiente para automação predial"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-adf.c",
|
||||
"exemplos": "https://github.com/espressif/esp-adf/tree/master/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-adf/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-adf",
|
||||
"cor": "#0284C7"
|
||||
},
|
||||
"ESP-SR": {
|
||||
"nome": "ESP-SR",
|
||||
"icone": "🎙️",
|
||||
"nome_completo": "ESP Speech Recognition Framework",
|
||||
"descricao": "Framework de reconhecimento de fala local e processamento de áudio com IA na borda (Edge AI), permitindo comandos de voz sem depender de conexão à internet.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Framework de Voz & IA",
|
||||
"funcao_principal": "Processamento de voz local, detecção de palavra de ativação (Wake Word) e reconhecimento de comandos de fala em tempo real",
|
||||
"caracteristicas": [
|
||||
"WakeNet: Detecção precisa de Wake Words locais (como 'Hi, ESP' e palavras personalizadas)",
|
||||
"MultiNet: Reconhecimento de até centenas de comandos de voz locais offline em português, inglês e mandarim",
|
||||
"AFE (Audio Front-End): Cancelamento acústico de eco (AEC), supressão de ruído (BSS/NS) e controle automático de ganho (AGC)",
|
||||
"Suporte a múltiplos microfones com formação de feixe direcional (Beamforming)",
|
||||
"Otimizado com aceleração vetorial SIMD para ESP32-S3 e ESP32-P4",
|
||||
"Componente disponível no ESP Component Registry (espressif/esp-sr)"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Eletrodomésticos com controle por voz 100% offline e privativo",
|
||||
"Painéis de automação residencial acionados por fala",
|
||||
"Brinquedos interativos e robótica educacional",
|
||||
"Equipamentos hospitalares e industriais com comando sem as mãos"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-sr.c",
|
||||
"exemplos": "https://github.com/espressif/esp-sr/tree/master/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-sr/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-sr",
|
||||
"cor": "#6366F1"
|
||||
},
|
||||
"ESP-IoT-Solution": {
|
||||
"nome": "ESP-IoT-Solution",
|
||||
"icone": "🧩",
|
||||
"nome_completo": "ESP-IoT-Solution Driver & Peripheral Suite",
|
||||
"descricao": "Coleção oficial da Espressif com dezenas de drivers, componentes de periféricos, telas touch, sensores e protocolos de barramento prontos para produção.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Biblioteca de Periféricos & Drivers",
|
||||
"funcao_principal": "Acelerar a integração de componentes de hardware (telas LCD/OLED, sensores ambientais/IMU, botões inteligentes, barramentos I2C/SPI/Modbus)",
|
||||
"caracteristicas": [
|
||||
"Drivers completos de sensores (temperatura, umidade, pressão, acelerômetros, luz)",
|
||||
"Gerenciamento avançado de botões físicos, matrizes touch e encoders rotativos",
|
||||
"Drivers para displays LCD e OLED (ST7789, ILI9341, SSD1306) e controladores touch (FT6X36, GT911)",
|
||||
"Pilha industrial Modbus (Master e Slave sobre RS-485 ou TCP)",
|
||||
"Controle de motores de passo e drivers de LED endereçável (WS2812/SK6812)",
|
||||
"Totalmente modularizado no ESP Component Registry"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Interfaces homem-máquina (IHM / HMI) com telas e botões capacitivos",
|
||||
"Estações meteorológicas e monitoramento de sensores industriais",
|
||||
"Equipamentos de automação industrial integrados via RS-485 Modbus",
|
||||
"Projetos com fitas e matrizes de LED RGB complexas"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-iot-solution.c",
|
||||
"exemplos": "https://github.com/espressif/esp-iot-solution/tree/master/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-iot-solution/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-iot-solution",
|
||||
"cor": "#10B981"
|
||||
},
|
||||
"ESP-NOW": {
|
||||
"nome": "ESP-NOW & Mesh",
|
||||
"icone": "📡",
|
||||
"nome_completo": "ESP-NOW Protocol & Mesh-Lite",
|
||||
"descricao": "Protocolo de comunicação sem fio de ultra-baixa latência desenvolvido pela Espressif, operando na faixa de 2.4 GHz sem a necessidade de um roteador Wi-Fi tradicional.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Protocolo de Rede & Mesh",
|
||||
"funcao_principal": "Troca de mensagens ponto-a-ponto, broadcast e formação de redes em malha leves entre dezenas de placas ESP32",
|
||||
"caracteristicas": [
|
||||
"Comunicação direta sem roteador ou ponto de acesso (AP)",
|
||||
"Latência de transmissão de milissegundos e conexão instantânea",
|
||||
"Criptografia nativa com chaves de chaveamento AES-128",
|
||||
"Extremamente econômico em energia, ideal para nós alimentados por bateria",
|
||||
"Capacidade de emparelhamento por controle remoto e broadcast para múltiplos nós",
|
||||
"Suporte ao Mesh-Lite para roteamento em malha com salto IP"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Controles remotos sem fio e interruptores de parede a bateria",
|
||||
"Redes de sensores agrícolas distribuídas no campo",
|
||||
"Sincronização em tempo real de iluminação cênica e drones",
|
||||
"Alarmes e botões de pânico residenciais"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-now.c",
|
||||
"exemplos": "https://github.com/espressif/esp-now/tree/master/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html",
|
||||
"repositorio": "https://github.com/espressif/esp-now",
|
||||
"cor": "#8B5CF6"
|
||||
},
|
||||
"ESP-Zigbee-SDK": {
|
||||
"nome": "ESP-Zigbee-SDK",
|
||||
"icone": "🐝",
|
||||
"nome_completo": "ESP Zigbee SDK (ZCL & ZBOSS)",
|
||||
"descricao": "SDK oficial para desenvolvimento de nós, roteadores e coordenadores Zigbee 3.0 nos SoCs ESP32 com suporte ao rádio 802.15.4 (como ESP32-H2 e ESP32-C6).",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Smart Home & Mesh",
|
||||
"funcao_principal": "Construção de redes de automação predial ultraleves e de baixíssimo consumo energético baseadas no padrão Zigbee 3.0",
|
||||
"caracteristicas": [
|
||||
"Implementação certificada Zigbee 3.0 baseada na stack ZBOSS",
|
||||
"Suporte a papéis de Coordenador (ZC), Roteador (ZR) e Dispositivo Final (ZED / Sleepy End Device)",
|
||||
"Biblioteca rica de clusters ZCL (On/Off, Nível, Cor, Temperatura, Medição de Energia)",
|
||||
"Consumo em microampères durante sono profundo para sensores operando por anos a bateria",
|
||||
"Compatibilidade nativa com pontes Zigbee (Home Assistant ZHA/Zigbee2MQTT, Philips Hue)"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Sensores de presença, porta/janela e vazamento operando a pilha botão",
|
||||
"Lâmpadas e tomadas inteligentes na rede Zigbee 3.0",
|
||||
"Gateways e pontes Zigbee-para-Wi-Fi ou Zigbee-para-Ethernet",
|
||||
"Automação predial comercial com alta densidade de nós"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-zigbee.c",
|
||||
"exemplos": "https://github.com/espressif/esp-zigbee-sdk/tree/main/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-zigbee-sdk/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-zigbee-sdk",
|
||||
"cor": "#EC4899"
|
||||
},
|
||||
"ESP-WHO": {
|
||||
"nome": "ESP-WHO",
|
||||
"icone": "📷",
|
||||
"nome_completo": "ESP Image Processing & Vision Framework",
|
||||
"descricao": "Framework da Espressif para processamento de imagens e visão computacional na borda (Edge Vision) com câmeras conectadas ao ESP32.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Visão Computacional & IA",
|
||||
"funcao_principal": "Detecção de rostos, identificação biométrica, detecção de pessoas e processamento de stream de vídeo",
|
||||
"caracteristicas": [
|
||||
"Detecção de faces em tempo real e extração de marcos faciais (Landmarks)",
|
||||
"Reconhecimento facial local com banco de dados de usuários cadastrados",
|
||||
"Detecção de presença humana e contagem de pessoas (Human Detection)",
|
||||
"Otimizado para ESP32-S3 e ESP32-P4 com instruções vetoriais de IA",
|
||||
"Suporte a sensores de câmera DVP e MIPI-CSI (OV2640, OV3660, OV5640, SC030IOT)"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Controle de acesso por biometria facial",
|
||||
"Campainhas e câmeras de segurança inteligentes (Smart Doorbells)",
|
||||
"Sensores inteligentes de ocupação de salas e escritórios",
|
||||
"Robôs seguidores de pessoas e brinquedos interativos"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-who.c",
|
||||
"exemplos": "https://github.com/espressif/esp-who/tree/master/examples",
|
||||
"documentacao": "https://github.com/espressif/esp-who",
|
||||
"repositorio": "https://github.com/espressif/esp-who",
|
||||
"cor": "#F97316"
|
||||
},
|
||||
"ESP-NN": {
|
||||
"nome": "ESP-NN",
|
||||
"icone": "🧠",
|
||||
"nome_completo": "ESP Neural Network Acceleration Library",
|
||||
"descricao": "Biblioteca de kernels e operações de redes neurais altamente otimizada para as arquiteturas Xtensa e RISC-V dos chips ESP32.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Biblioteca Especializada de IA",
|
||||
"funcao_principal": "Aceleração de inferência de redes neurais profundas com quantização INT8 e INT16 aproveitando as instruções SIMD vetoriais",
|
||||
"caracteristicas": [
|
||||
"Operações otimizadas: Convolução 2D, Depthwise Conv, Fully Connected e Pooling",
|
||||
"Backend acelerador oficial integrado ao TensorFlow Lite for Microcontrollers (TFLM)",
|
||||
"Quantização eficiente de 8 e 16 bits para redução drástica de uso de RAM e Flash",
|
||||
"Aceleração extrema no ESP32-S3 e ESP32-P4 usando instruções vetoriais dedicadas",
|
||||
"Execução sem overhead de sistema operacional em tempo real"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Classificação de áudio e sinais de vibração industrial (manutenção preditiva)",
|
||||
"Detecção de anomalias em sensores por modelos TinyML",
|
||||
"Reconhecimento de gestos por IMU",
|
||||
"Visão computacional ultraleve em microcontroladores"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-nn.c",
|
||||
"exemplos": "https://github.com/espressif/esp-nn/tree/master/test_app",
|
||||
"documentacao": "https://github.com/espressif/esp-nn",
|
||||
"repositorio": "https://github.com/espressif/esp-nn",
|
||||
"cor": "#14B8A6"
|
||||
},
|
||||
"ESP-DSP": {
|
||||
"nome": "ESP-DSP",
|
||||
"icone": "📊",
|
||||
"nome_completo": "ESP Digital Signal Processing Library",
|
||||
"descricao": "Biblioteca oficial de processamento digital de sinais para a família ESP32, fornecendo algoritmos matemáticos acelerados em hardware.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Biblioteca Especializada de Sinais",
|
||||
"funcao_principal": "Execução de cálculos matemáticos pesados como FFT, transformadas, filtragem digital e operações matriciais com máxima velocidade",
|
||||
"caracteristicas": [
|
||||
"Transformadas Rápidas de Fourier (FFT real e complexa) otimizadas em Assembly",
|
||||
"Filtros digitais IIR, FIR e estimadores de Kalman",
|
||||
"Operações com matrizes, vetores e produtos escalares",
|
||||
"Suporte a números de ponto flutuante e ponto fixo (Radix-2 e Radix-4)",
|
||||
"Otimizações personalizadas para arquiteturas Xtensa Dual-Core e RISC-V"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Análise espectral de áudio e vibrações em tempo real",
|
||||
"Filtros anti-ruído para sensores biomédicos (ECG/EMG) e industriais",
|
||||
"Controle de motores de alta precisão e algoritmos FOC",
|
||||
"Compressão e codificação de dados na borda"
|
||||
],
|
||||
"exemplo": "/exemplos/esp-dsp.c",
|
||||
"exemplos": "https://github.com/espressif/esp-dsp/tree/master/examples",
|
||||
"documentacao": "https://docs.espressif.com/projects/esp-dsp/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/esp-dsp",
|
||||
"cor": "#A855F7"
|
||||
},
|
||||
"Rust-ESP": {
|
||||
"nome": "Rust on ESP32",
|
||||
"icone": "🦀",
|
||||
"nome_completo": "ESP-RS Rust Ecosystem for ESP32",
|
||||
"descricao": "Ecossistema moderno de desenvolvimento em linguagem Rust para a família ESP32, combinando segurança de memória (Memory Safety), concorrência robusta e alto desempenho.",
|
||||
"linguagem": "Rust",
|
||||
"tipo": "Linguagem & Framework Moderno",
|
||||
"funcao_principal": "Desenvolvimento de firmware seguro e de alta performance tanto em modo bare-metal (no_std via esp-hal) quanto com a pilha completa (std via esp-idf-svc)",
|
||||
"caracteristicas": [
|
||||
"Modo Bare-Metal `no_std` com a biblioteca `esp-hal`: controle total sem RTOS e boot ultrarrápido",
|
||||
"Modo `std` com `esp-idf-svc`: acesso à biblioteca padrão do Rust, Wi-Fi, BLE, HTTP, MQTT e threads",
|
||||
"Prevenção garantida em tempo de compilação contra corrupção de memória e Data Races",
|
||||
"Suporte a targets Xtensa (ESP32, S2, S3) e RISC-V nativo (C2, C3, C6, H2, P4)",
|
||||
"Integração com ecossistema de crates `embedded-hal` e async/await com `embassy`",
|
||||
"Ferramentas oficiais: `espflash` para gravação e monitor serial e `esp-generate` para templates"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Sistemas críticos onde falhas de memória (Null Pointer, Buffer Overflow) são inaceitáveis",
|
||||
"Aplicações IoT modernas com concorrência assíncrona limpa",
|
||||
"Dispositivos industriais que exigem segurança de alto nível",
|
||||
"Projetos modernos de robótica e instrumentação"
|
||||
],
|
||||
"exemplo": "/exemplos/rust-esp.rs",
|
||||
"exemplos": "https://github.com/esp-rs/esp-hal/tree/main/examples",
|
||||
"documentacao": "https://esp-rs.github.io/book/",
|
||||
"repositorio": "https://github.com/esp-rs",
|
||||
"cor": "#E44D26"
|
||||
},
|
||||
"Arduino": {
|
||||
"nome": "Arduino Core",
|
||||
"icone": "🛠️",
|
||||
"nome_completo": "Arduino Core for ESP32",
|
||||
"descricao": "Implementação oficial do framework Arduino sobre o ESP-IDF (versões 3.x+ baseadas em ESP-IDF v5.1+), combinando extrema facilidade com os recursos avançados do ESP32.",
|
||||
"linguagem": "C++",
|
||||
"tipo": "Framework Alternativo Popular",
|
||||
"funcao_principal": "Prototipagem rápida, projetos educacionais e desenvolvimento acelerado aproveitando o vasto ecossistema de bibliotecas Arduino",
|
||||
"caracteristicas": [
|
||||
"Sintaxe clássica `setup()` e `loop()` com centenas de milhares de bibliotecas compatíveis",
|
||||
"Execução como uma tarefa FreeRTOS sobre o ESP-IDF oficial",
|
||||
"Suporte completo a Wi-Fi, Bluetooth Classic/BLE, WebServer e WebSockets",
|
||||
"Compatibilidade com Arduino IDE 2.x, PlatformIO e VS Code",
|
||||
"Suporte atualizado a todos os SoCs populares (ESP32, S2, S3, C3, C6)",
|
||||
"Acesso a funções nativas do ESP-IDF quando necessário"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Prototipagem rápida e validação de conceitos (PoC)",
|
||||
"Projetos educacionais, makers e acadêmicos",
|
||||
"Sistemas IoT simples com dashboards (Blynk, Adafruit IO, ThingSpeak)",
|
||||
"Robótica amadora e automação residencial faça-você-mesmo (DIY)"
|
||||
],
|
||||
"exemplo": "/exemplos/arduino.ino",
|
||||
"exemplos": "https://github.com/espressif/arduino-esp32/tree/master/docs/en/tutorials",
|
||||
"documentacao": "https://docs.espressif.com/projects/arduino-esp32/en/latest/",
|
||||
"repositorio": "https://github.com/espressif/arduino-esp32",
|
||||
"cor": "#00979D"
|
||||
},
|
||||
"MicroPython": {
|
||||
"nome": "MicroPython",
|
||||
"icone": "🐍",
|
||||
"nome_completo": "MicroPython for ESP32",
|
||||
"descricao": "Implementação enxuta e eficiente da linguagem Python 3 otimizada para rodar diretamente na CPU do ESP32 com interpretador em tempo real.",
|
||||
"linguagem": "Python",
|
||||
"tipo": "Linguagem & Interpretador Dinâmico",
|
||||
"funcao_principal": "Desenvolvimento interativo e prototipagem ágil em Python com console REPL interativo e manipulação instantânea de hardware",
|
||||
"caracteristicas": [
|
||||
"Interpretador Python 3 completo com compilação para bytecode em RAM",
|
||||
"Console interativo REPL via porta serial e WebREPL via Wi-Fi",
|
||||
"Sistema de arquivos integrado (LittleFS / FAT) com upload de scripts `.py` sem recompilar",
|
||||
"Módulos nativos `machine`, `network`, `bluetooth`, `espnow` e `asyncio`",
|
||||
"Excelente para ensinar programação e algoritmos com hardware real"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Ensino de computação física e laboratórios universitários",
|
||||
"Prototipagem ágil e testes rápidos de sensores em bancada",
|
||||
"Scripts de automação de testes de bancada",
|
||||
"Aplicações experimentais de coleta de dados IoT"
|
||||
],
|
||||
"exemplo": "/exemplos/micropython.py",
|
||||
"exemplos": "https://github.com/micropython/micropython/tree/master/examples",
|
||||
"documentacao": "https://docs.micropython.org/en/latest/esp32/",
|
||||
"repositorio": "https://github.com/micropython/micropython",
|
||||
"cor": "#2B2B2B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,732 @@
|
||||
{
|
||||
"ESP32": {
|
||||
"nome_completo": "ESP32 (Clássico)",
|
||||
"icone": "🔷",
|
||||
"descricao": "O modelo original com processador dual-core e ampla gama de periféricos",
|
||||
"arquitetura": "Xtensa® LX6 dual-core de 32 bits",
|
||||
"nucleos": "1 (Single-core) ou 2 (Dual-core)",
|
||||
"frequencia": "Até 240 MHz",
|
||||
"coprocessador_ulp": "Sim",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/192/256",
|
||||
"sha": "SHA-1/256/384/512",
|
||||
"rsa": "Sim (RSA/MPI até 4096 bits)",
|
||||
"ecc": "Não",
|
||||
"ecdsa": "Não",
|
||||
"hmac": "Não",
|
||||
"assinatura_digital": "Não",
|
||||
"key_manager": "Não",
|
||||
"rng": "Sim (TRNG por hardware)",
|
||||
"criptografia_flash": "Sim (AES-256, esquema legado)",
|
||||
"secure_boot": "V1 (AES, legado); V2 (RSA-3072, RSA-PSS) a partir da revisão v3.0 (ECO3)",
|
||||
"protecao_dpa": "Não"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, até 150 Mbps)",
|
||||
"bluetooth": "Bluetooth 4.2 BR/EDR (Clássico) e Bluetooth LE (dual mode)",
|
||||
"ethernet": "Sim (Ethernet MAC integrado)",
|
||||
"memoria_sram": "520 KB",
|
||||
"memoria_sram_rtc": "16 KB (dividida em RTC FAST e RTC SLOW)",
|
||||
"memoria_rom": "448 KB (para boot e funções core)",
|
||||
"flash_externa": "Até 16 MB via QSPI",
|
||||
"psram_externa": "Até 8 MB via QSPI (em módulos específicos como WROVER)",
|
||||
"gpio": "34",
|
||||
"adc": "2x SAR ADC de 12 bits, até 18 canais",
|
||||
"dac": "2x DAC de 8 bits",
|
||||
"touch": "10 canais capacitivos",
|
||||
"uart": "3",
|
||||
"spi": "4 (SPI, HSPI, VSPI - 2 podem ser usados para Flash/PSRAM)",
|
||||
"i2c": "2",
|
||||
"i2s": "2",
|
||||
"pwm": "LED PWM (até 16 canais), Motor PWM",
|
||||
"ethernet_mac": "1 (requer PHY externo)",
|
||||
"can": "1 (CAN 2.0, TWAI®)",
|
||||
"sdio": "1 (SD/SDIO/MMC Host), 1 (SDIO/SPI Slave)",
|
||||
"sensor_hall": "1 (interno)",
|
||||
"sensor_temperatura": "Não (retirado do datasheet em 2018; sem driver no ESP-IDF)",
|
||||
"consumo_energia": {
|
||||
"active_cpu_240mhz": "30-68 mA",
|
||||
"active_wifi_tx": "180-240 mA",
|
||||
"modem_sleep": "20-44 mA",
|
||||
"light_sleep": "0.8 mA",
|
||||
"deep_sleep": "10-150 µA",
|
||||
"hibernation": "5 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 125°C",
|
||||
"temperatura_armazenamento": "-40°C a 150°C",
|
||||
"depuracao": "JTAG externo (requer sonda, ex.: ESP-PROG)",
|
||||
"esp_idf_minimo": "Desde o início (v3.x e anteriores)",
|
||||
"arduino_core": "Sim (147 definições de placa no core oficial)",
|
||||
"encapsulamento": "QFN48 (6×6 mm) e QFN48 (5×5 mm)",
|
||||
"modulos": "ESP32-MINI-1, ESP32-PICO-MINI-02, ESP32-PICO-V3, ESP32-PICO-V3-02 e mais 11",
|
||||
"datasheet": "https://documentation.espressif.com/esp32_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html",
|
||||
"placa": "/placas/esp32.png",
|
||||
"cor": "#007bff"
|
||||
},
|
||||
"ESP32-S2": {
|
||||
"nome_completo": "ESP32-S2",
|
||||
"icone": "🔒",
|
||||
"descricao": "Foco em segurança e baixo consumo, com USB nativo e o único ADC com saída de 13 bits",
|
||||
"arquitetura": "Xtensa® LX7 single-core de 32 bits",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Até 240 MHz",
|
||||
"coprocessador_ulp": "Sim (RISC-V)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/192/256 com GCM",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Sim (RSA/MPI até 4096 bits)",
|
||||
"ecc": "Não",
|
||||
"ecdsa": "Não",
|
||||
"hmac": "Sim",
|
||||
"assinatura_digital": "Sim",
|
||||
"key_manager": "Não",
|
||||
"rng": "Sim (TRNG por hardware)",
|
||||
"criptografia_flash": "XTS-AES-128/256",
|
||||
"secure_boot": "V2 (RSA-3072)",
|
||||
"protecao_dpa": "Não"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, até 150 Mbps)",
|
||||
"bluetooth": "Não",
|
||||
"memoria_sram": "320 KB",
|
||||
"memoria_sram_rtc": "16 KB",
|
||||
"memoria_rom": "128 KB",
|
||||
"flash_externa": "Até 1 GB via QSPI",
|
||||
"psram_externa": "Até 1 GB via QSPI/Octal SPI",
|
||||
"gpio": "43",
|
||||
"adc": "2x SAR ADC, até 20 canais: saída de 13 bits (0–8191, única da família), resolução efetiva de 12 bits a partir da revisão v1.0 (errata ADC-112)",
|
||||
"dac": "2x DAC de 8 bits",
|
||||
"touch": "14 canais capacitivos",
|
||||
"uart": "2",
|
||||
"spi": "4 (SPI0/1 para Flash, SPI2/3 para uso geral)",
|
||||
"i2c": "2",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (até 8 canais)",
|
||||
"usb": "1 (USB OTG 1.1 Full-Speed)",
|
||||
"lcd": "Interface LCD de 8/16 bits",
|
||||
"camera": "Interface DVP de 8/16 bits",
|
||||
"sensor_temperatura": "1 (interno)",
|
||||
"consumo_energia": {
|
||||
"active_wifi_tx": "160-310 mA",
|
||||
"modem_sleep_cpu_160mhz": "14-24 mA",
|
||||
"light_sleep": "750 µA",
|
||||
"deep_sleep": "20-190 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 105°C",
|
||||
"temperatura_armazenamento": "-40°C a 150°C",
|
||||
"depuracao": "JTAG externo (requer sonda, ex.: ESP-PROG)",
|
||||
"esp_idf_minimo": "v4.2",
|
||||
"arduino_core": "Sim (26 definições de placa no core oficial)",
|
||||
"encapsulamento": "QFN56 (7×7 mm)",
|
||||
"modulos": "ESP32-S2-MINI-1, ESP32-S2-MINI-2, ESP32-S2-SOLO, ESP32-S2-SOLO-2 e mais 4",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-s2_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-s2_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html",
|
||||
"placa": "/placas/esp32-s2.png",
|
||||
"cor": "#28a745"
|
||||
},
|
||||
"ESP32-S3": {
|
||||
"nome_completo": "ESP32-S3",
|
||||
"icone": "🤖",
|
||||
"descricao": "Processador dual-core com aceleradores para IA e processamento de sinal",
|
||||
"arquitetura": "Xtensa® LX7 dual-core de 32 bits",
|
||||
"nucleos": "2 (Dual-core)",
|
||||
"frequencia": "Até 240 MHz",
|
||||
"coprocessador_ulp": "Sim (RISC-V)",
|
||||
"aceleradores_ia": "Sim (Vector Instructions para IA)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Sim (RSA/MPI até 4096 bits)",
|
||||
"ecc": "Não",
|
||||
"ecdsa": "Não",
|
||||
"hmac": "Sim",
|
||||
"assinatura_digital": "Sim",
|
||||
"key_manager": "Não",
|
||||
"rng": "Sim (TRNG por hardware)",
|
||||
"criptografia_flash": "XTS-AES-128/256",
|
||||
"secure_boot": "V2 (RSA-3072)",
|
||||
"protecao_dpa": "Não"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, até 150 Mbps)",
|
||||
"bluetooth": "Bluetooth 5 (LE) e Bluetooth Mesh",
|
||||
"memoria_sram": "512 KB",
|
||||
"memoria_sram_rtc": "16 KB",
|
||||
"memoria_rom": "384 KB",
|
||||
"flash_externa": "Até 1 GB via QSPI/Octal SPI",
|
||||
"psram_externa": "Até 1 GB via QSPI/Octal SPI",
|
||||
"gpio": "45",
|
||||
"adc": "2x SAR ADC de 12 bits, até 20 canais",
|
||||
"dac": "Não",
|
||||
"touch": "14 canais capacitivos",
|
||||
"uart": "3",
|
||||
"spi": "4 (SPI0/1 para Flash, SPI2/3 para uso geral)",
|
||||
"i2c": "2",
|
||||
"i2s": "2",
|
||||
"pwm": "LED PWM (até 8 canais), Motor PWM (6 canais)",
|
||||
"usb": "1 (USB OTG 1.1 Full-Speed) + 1 (USB Serial/JTAG)",
|
||||
"lcd": "Interface LCD RGB de 8/16 bits",
|
||||
"camera": "Interface DVP de 8/16 bits",
|
||||
"sdio": "1 (SD/SDIO/MMC Host)",
|
||||
"sensor_temperatura": "1 (interno)",
|
||||
"consumo_energia": {
|
||||
"active": "78 mW (~24 mA @3.3V)",
|
||||
"modem_sleep": "13-42 mA (40-80 MHz, conforme a carga)",
|
||||
"light_sleep": "240 µA (+40 a 200 µA da PSRAM)",
|
||||
"deep_sleep": "7 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 65/85/105°C",
|
||||
"temperatura_armazenamento": "-40°C a 150°C",
|
||||
"depuracao": "JTAG integrado via USB (não precisa de sonda externa)",
|
||||
"esp_idf_minimo": "v4.4",
|
||||
"arduino_core": "Sim (158 definições de placa no core oficial)",
|
||||
"encapsulamento": "QFN56 (7×7 mm)",
|
||||
"modulos": "ESP32-S3-MINI-1, ESP32-S3-WROOM-1, ESP32-S3-WROOM-2",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-s3_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-s3_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/get-started/index.html",
|
||||
"placa": "/placas/esp32-s3.png",
|
||||
"cor": "#fd7e14"
|
||||
},
|
||||
"ESP32-S31": {
|
||||
"nome_completo": "ESP32-S31",
|
||||
"icone": "🌀",
|
||||
"descricao": "Processador dual-core RISC-V de alta performance a 320MHz com Wi-Fi 6, Bluetooth 5.4 e Classic, Zigbee/Thread, Matter e aceleração IA",
|
||||
"arquitetura": "RISC-V dual-core de 32 bits (HP) + RISC-V single-core (LP)",
|
||||
"nucleos": "2 (Dual-core HP) + 1 (Single-core LP)",
|
||||
"frequencia": "Até 320 MHz",
|
||||
"coprocessador_ulp": "Sim (RISC-V, LP CPU de 40 MHz)",
|
||||
"aceleradores_ia": "Sim (Custom AI and DSP extension XespV)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256 com GCM",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Sim (RSA/MPI até 4096 bits)",
|
||||
"ecc": "Sim (P-192, P-256, P-384)",
|
||||
"ecdsa": "Sim (modo determinístico, RFC 6979)",
|
||||
"hmac": "Sim",
|
||||
"assinatura_digital": "Sim",
|
||||
"key_manager": "Sim",
|
||||
"rng": "Sim (TRNG por hardware)",
|
||||
"criptografia_flash": "XTS-AES-128/256",
|
||||
"secure_boot": "V2 (RSA-3072)",
|
||||
"protecao_dpa": "Sim"
|
||||
},
|
||||
"wifi": "Wi-Fi 6 (802.11ax) 2.4 GHz",
|
||||
"bluetooth": "Bluetooth 5.4 LE e Bluetooth Classic",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0, Thread 1.4)",
|
||||
"matter": "Sim",
|
||||
"memoria_sram": "512 KB (HP SRAM)",
|
||||
"memoria_sram_rtc": "32 KB (LP SRAM)",
|
||||
"memoria_rom": "320 KB",
|
||||
"flash_externa": "Até 256 MB via QSPI",
|
||||
"psram_externa": "16 MB ou 32 MB octal DDR, só dentro do encapsulamento (NRV16, NRV32)",
|
||||
"gpio": "60",
|
||||
"adc": "2x SAR ADC de 12 bits, até 16 canais",
|
||||
"dac": "Sim (2x DAC de 10 bits e 2x DAC de 12 bits)",
|
||||
"touch": "14 canais capacitivos",
|
||||
"uart": "5 (4 UART + 1 LP UART)",
|
||||
"spi": "7 (6 SPI + 1 LP SPI)",
|
||||
"i2c": "3 (2 I2C + 1 LP I2C)",
|
||||
"i2s": "2",
|
||||
"pwm": "LED PWM (até 8 canais), Motor PWM (MCPWM)",
|
||||
"usb": "1 (USB 2.0 High-Speed OTG e USB Serial/JTAG)",
|
||||
"can": "Sim (CAN FD Controller)",
|
||||
"sensor_temperatura": "1 (interno)",
|
||||
"consumo_energia": {
|
||||
"active": "Consumo otimizado de alta performance configurável",
|
||||
"light_sleep": "0.1-0.8 mA",
|
||||
"deep_sleep": "Baixo consumo com LP CPU ativa"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 85°C",
|
||||
"temperatura_armazenamento": "-40°C a 150°C",
|
||||
"depuracao": "JTAG integrado via USB (não precisa de sonda externa)",
|
||||
"esp_idf_minimo": "v6.1 em preview; suporte oficial a partir da v6.1.1",
|
||||
"arduino_core": "Ainda não suportado pelo core arduino-esp32",
|
||||
"encapsulamento": "QFN80 (8×8 mm)",
|
||||
"modulos": "ESP32-S31-WROOM-1, ESP32-S31-WROOM-3",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-s31_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-s31_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s31/get-started/index.html",
|
||||
"placa": "/placas/esp32-s31.png",
|
||||
"cor": "#ff2a5f",
|
||||
"sdio": "1 (SDIO Host 3.0)"
|
||||
},
|
||||
"ESP32-C2": {
|
||||
"nome_completo": "ESP32-C2 (ESP8684)",
|
||||
"icone": "🌱",
|
||||
"descricao": "Microcontrolador RISC-V ultra econômico e de baixo consumo com Wi-Fi 4 e Bluetooth 5.3 LE",
|
||||
"arquitetura": "RISC-V single-core de 32 bits",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Até 120 MHz",
|
||||
"seguranca": {
|
||||
"aes": "Não",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "Não",
|
||||
"ecc": "Sim (P-192, P-256)",
|
||||
"ecdsa": "Não",
|
||||
"hmac": "Não",
|
||||
"assinatura_digital": "Não",
|
||||
"key_manager": "Não",
|
||||
"rng": "Sim (TRNG por hardware)",
|
||||
"criptografia_flash": "XTS-AES-128",
|
||||
"secure_boot": "V2 (ECDSA P-192 ou P-256)",
|
||||
"protecao_dpa": "Não"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, até 72.2 Mbps)",
|
||||
"bluetooth": "Bluetooth 5.3 LE (certificado)",
|
||||
"memoria_sram": "272 KB (16 KB para cache)",
|
||||
"memoria_sram_rtc": "Não",
|
||||
"memoria_rom": "576 KB",
|
||||
"flash_externa": "Até 16 MB via QSPI, mas indisponível nas variantes vendidas (ESP8684H2X/H4X têm 2 MB ou 4 MB no encapsulamento e não expõem os pinos de flash)",
|
||||
"psram_externa": "Não",
|
||||
"gpio": "14",
|
||||
"adc": "1x SAR ADC de 12 bits, até 5 canais",
|
||||
"dac": "Não",
|
||||
"touch": "Não",
|
||||
"uart": "2",
|
||||
"spi": "3 (SPI0/1 para Flash interna, SPI2 para uso geral)",
|
||||
"i2c": "1 (Master-only)",
|
||||
"i2s": "Não",
|
||||
"pwm": "LED PWM (até 6 canais)",
|
||||
"sensor_temperatura": "1 (interno)",
|
||||
"consumo_energia": {
|
||||
"active_cpu_120mhz": "10,7-15,6 mA (modem-sleep)",
|
||||
"light_sleep": "140 µA",
|
||||
"deep_sleep": "5 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 105°C",
|
||||
"temperatura_armazenamento": "-40°C a 150°C",
|
||||
"depuracao": "JTAG externo (requer sonda, ex.: ESP-PROG)",
|
||||
"esp_idf_minimo": "v5.0",
|
||||
"arduino_core": "Sim (1 definições de placa no core oficial)",
|
||||
"encapsulamento": "QFN24 (4×4 mm)",
|
||||
"modulos": "ESP8684-MINI-1, ESP8684-WROOM-01C, ESP8684-WROOM-02C, ESP8684-WROOM-02UC e mais 5",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-c2_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-c2_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c2/get-started/index.html",
|
||||
"placa": "/placas/esp32-c2.png",
|
||||
"cor": "#8c52ff"
|
||||
},
|
||||
"ESP32-C3": {
|
||||
"nome_completo": "ESP32-C3",
|
||||
"icone": "💎",
|
||||
"descricao": "Processador RISC-V de ultra baixo consumo",
|
||||
"arquitetura": "RISC-V single-core de 32 bits",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Até 160 MHz",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "Sim (RSA/MPI até 3072 bits)",
|
||||
"ecc": "Não",
|
||||
"ecdsa": "Não",
|
||||
"hmac": "Sim",
|
||||
"assinatura_digital": "Sim",
|
||||
"key_manager": "Não",
|
||||
"rng": "Sim (TRNG por hardware)",
|
||||
"criptografia_flash": "XTS-AES-128",
|
||||
"secure_boot": "V2 (RSA-3072), a partir da revisão v0.3 (ECO3)",
|
||||
"protecao_dpa": "Não"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, até 150 Mbps)",
|
||||
"bluetooth": "Bluetooth 5 (LE) e Bluetooth Mesh",
|
||||
"memoria_sram": "400 KB",
|
||||
"memoria_sram_rtc": "8 KB",
|
||||
"memoria_rom": "384 KB",
|
||||
"flash_externa": "Até 16 MB via QSPI",
|
||||
"psram_externa": "Não",
|
||||
"gpio": "22",
|
||||
"adc": "2x SAR ADC de 12 bits, até 6 canais",
|
||||
"dac": "Não",
|
||||
"touch": "Não",
|
||||
"uart": "2",
|
||||
"spi": "3 (SPI0/1 para Flash, SPI2 para uso geral)",
|
||||
"i2c": "1",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (até 6 canais)",
|
||||
"usb": "1 (USB Serial/JTAG)",
|
||||
"sensor_temperatura": "1 (interno)",
|
||||
"consumo_energia": {
|
||||
"active_cpu_160mhz": "20 mA",
|
||||
"active_wifi_tx_peak": "335 mA",
|
||||
"modem_sleep_cpu_160mhz": "16-28 mA",
|
||||
"light_sleep": "130 µA",
|
||||
"deep_sleep": "5 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 105°C (85°C no ESP32-C3FN4)",
|
||||
"temperatura_armazenamento": "-40°C a 150°C",
|
||||
"depuracao": "JTAG integrado via USB (não precisa de sonda externa)",
|
||||
"esp_idf_minimo": "v4.3",
|
||||
"arduino_core": "Sim (29 definições de placa no core oficial)",
|
||||
"encapsulamento": "QFN32 (5×5 mm) e QFN28 (4×4 mm)",
|
||||
"modulos": "ESP32-C3-MINI-1, ESP32-C3-WROOM-02",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-c3_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-c3_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/get-started/index.html",
|
||||
"placa": "/placas/esp32-c3.png",
|
||||
"cor": "#20c997"
|
||||
},
|
||||
"ESP32-C5": {
|
||||
"nome_completo": "ESP32-C5",
|
||||
"icone": "📶",
|
||||
"descricao": "O primeiro com suporte a Wi-Fi 6 dual-band e Bluetooth 6.0, equipado com CPU RISC-V e coprocessador ULP",
|
||||
"arquitetura": "RISC-V single-core de 32 bits (HP) + RISC-V single-core (LP)",
|
||||
"nucleos": "1 (Single-core HP) + 1 (Single-core LP)",
|
||||
"frequencia": "Até 240 MHz",
|
||||
"coprocessador_ulp": "Sim (RISC-V, LP CPU de 48 MHz)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Sim (RSA/MPI até 3072 bits)",
|
||||
"ecc": "Sim (P-192, P-256, P-384)",
|
||||
"ecdsa": "Sim (modo determinístico, RFC 6979)",
|
||||
"hmac": "Sim",
|
||||
"assinatura_digital": "Sim",
|
||||
"key_manager": "Sim",
|
||||
"rng": "Sim (TRNG por hardware)",
|
||||
"criptografia_flash": "XTS-AES-128/256",
|
||||
"secure_boot": "V2 (RSA-3072 ou ECDSA P-256/P-384)",
|
||||
"protecao_dpa": "Sim"
|
||||
},
|
||||
"wifi": "Wi-Fi 6 (802.11ax) dual-band 2.4 GHz e 5 GHz",
|
||||
"bluetooth": "Bluetooth 5 (LE) (Bluetooth Core 6.0 certificado)",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0, Thread 1.4)",
|
||||
"matter": "Sim",
|
||||
"memoria_sram": "384 KB",
|
||||
"memoria_sram_rtc": "16 KB",
|
||||
"memoria_rom": "320 KB",
|
||||
"flash_externa": "Até 16 MB via QSPI",
|
||||
"psram_externa": "Sim, via SPI (controlador de flash/PSRAM com cache)",
|
||||
"gpio": "29",
|
||||
"adc": "1x SAR ADC de 12 bits, até 6 canais",
|
||||
"dac": "Não",
|
||||
"touch": "Não",
|
||||
"uart": "3 (2 UART + 1 LP UART)",
|
||||
"spi": "3",
|
||||
"i2c": "2 (1 I2C + 1 LP I2C)",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (até 6 canais), Motor PWM",
|
||||
"usb": "1 (USB Serial/JTAG)",
|
||||
"sensor_temperatura": "1 (interno)",
|
||||
"consumo_energia": {
|
||||
"active_wifi": "até 377 mA (TX em 5 GHz)",
|
||||
"light_sleep": "60-250 µA",
|
||||
"deep_sleep": "12 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 105°C",
|
||||
"temperatura_armazenamento": "-40°C a 150°C",
|
||||
"depuracao": "JTAG integrado via USB (não precisa de sonda externa)",
|
||||
"esp_idf_minimo": "v5.5.2",
|
||||
"arduino_core": "Sim (10 definições de placa no core oficial)",
|
||||
"encapsulamento": "QFN48 (6×6 mm)",
|
||||
"modulos": "ESP32-C5-MINI-1, ESP32-C5-WROOM-1",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-c5_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-c5_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c5/get-started/index.html",
|
||||
"placa": "/placas/esp32-c5.png",
|
||||
"cor": "#6f42c1",
|
||||
"sdio": "1 (SDIO Slave, a partir da revisão v1.0)",
|
||||
"can": "2 (CAN FD)"
|
||||
},
|
||||
"ESP32-C6": {
|
||||
"nome_completo": "ESP32-C6",
|
||||
"icone": "🌐",
|
||||
"descricao": "Recursos de segurança avançada, Wi-Fi 6, Bluetooth 6.0, Zigbee e Thread com suporte a Matter",
|
||||
"arquitetura": "RISC-V single-core de 32 bits (HP) + RISC-V single-core (LP)",
|
||||
"nucleos": "1 (Single-core HP) + 1 (Single-core LP)",
|
||||
"frequencia": "Até 160 MHz",
|
||||
"coprocessador_ulp": "Sim (RISC-V, LP CPU de 20 MHz)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "Sim (RSA/MPI até 3072 bits)",
|
||||
"ecc": "Sim (P-192, P-256)",
|
||||
"ecdsa": "Não",
|
||||
"hmac": "Sim",
|
||||
"assinatura_digital": "Sim",
|
||||
"key_manager": "Não",
|
||||
"rng": "Sim (TRNG por hardware)",
|
||||
"criptografia_flash": "XTS-AES-128",
|
||||
"secure_boot": "V2 (RSA-3072 ou ECDSA)",
|
||||
"protecao_dpa": "Sim"
|
||||
},
|
||||
"wifi": "Wi-Fi 6 (802.11ax) 2.4 GHz",
|
||||
"bluetooth": "Bluetooth 5 (LE) (Bluetooth 5.3 certificado)",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0, Thread 1.3)",
|
||||
"matter": "Sim",
|
||||
"memoria_sram": "512 KB",
|
||||
"memoria_sram_rtc": "16 KB",
|
||||
"memoria_rom": "320 KB",
|
||||
"flash_externa": "Até 16 MB via QSPI",
|
||||
"psram_externa": "Não",
|
||||
"gpio": "30",
|
||||
"adc": "1x SAR ADC de 12 bits, até 7 canais",
|
||||
"dac": "Não",
|
||||
"touch": "Não",
|
||||
"uart": "3 (2 UART + 1 LP UART)",
|
||||
"spi": "3",
|
||||
"i2c": "2 (1 I2C + 1 LP I2C)",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (até 6 canais), Motor PWM",
|
||||
"usb": "1 (USB Serial/JTAG)",
|
||||
"sdio": "1 (SDIO 2.0 Slave)",
|
||||
"sensor_temperatura": "1 (interno)",
|
||||
"consumo_energia": {
|
||||
"active_wifi6": "252-354 mA (TX)",
|
||||
"light_sleep": "35-180 µA",
|
||||
"deep_sleep": "7 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 105°C",
|
||||
"temperatura_armazenamento": "-40°C a 150°C",
|
||||
"depuracao": "JTAG integrado via USB (não precisa de sonda externa)",
|
||||
"esp_idf_minimo": "v5.1",
|
||||
"arduino_core": "Sim (21 definições de placa no core oficial)",
|
||||
"encapsulamento": "QFN40 (5×5 mm) e QFN32 (5×5 mm)",
|
||||
"modulos": "ESP32-C6-MINI-1, ESP32-C6-WROOM-1",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-c6_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-c6_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/get-started/index.html",
|
||||
"placa": "/placas/esp32-c6.png",
|
||||
"cor": "#17a2b8"
|
||||
},
|
||||
"ESP32-C61": {
|
||||
"nome_completo": "ESP32-C61",
|
||||
"icone": "🛰️",
|
||||
"descricao": "Microcontrolador RISC-V econômico de 160MHz com Wi-Fi 6, Bluetooth 6.0 LE e suporte a Flash/PSRAM no encapsulamento",
|
||||
"arquitetura": "RISC-V single-core de 32 bits",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Até 160 MHz",
|
||||
"seguranca": {
|
||||
"aes": "Não",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "Não",
|
||||
"ecc": "Sim (P-192, P-256)",
|
||||
"ecdsa": "Sim (modo determinístico, RFC 6979)",
|
||||
"hmac": "Não",
|
||||
"assinatura_digital": "Não",
|
||||
"key_manager": "Não",
|
||||
"rng": "Sim (TRNG por hardware)",
|
||||
"criptografia_flash": "XTS-AES-128",
|
||||
"secure_boot": "V2 (ECDSA)",
|
||||
"protecao_dpa": "Sim"
|
||||
},
|
||||
"wifi": "Wi-Fi 6 (802.11ax) 2.4 GHz",
|
||||
"bluetooth": "Bluetooth 5 (LE) (Bluetooth Core 6.0 certificado)",
|
||||
"zigbee_thread": "Não",
|
||||
"matter": "Sim (via Wi-Fi)",
|
||||
"memoria_sram": "320 KB",
|
||||
"memoria_sram_rtc": "Não",
|
||||
"memoria_rom": "256 KB",
|
||||
"flash_externa": "Até 16 MB via QSPI (modelos com 4 MB ou 8 MB integrados no encapsulamento)",
|
||||
"psram_externa": "Até 16 MB via QSPI (modelos com 2 MB ou 8 MB integrados no encapsulamento)",
|
||||
"gpio": "30",
|
||||
"adc": "1x SAR ADC de 12 bits, até 4 canais",
|
||||
"dac": "Não",
|
||||
"touch": "Não",
|
||||
"uart": "3",
|
||||
"spi": "3 (2 para Flash/PSRAM, 1 para uso geral)",
|
||||
"i2c": "1",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (até 6 canais)",
|
||||
"usb": "1 (USB Serial/JTAG)",
|
||||
"sdio": "1 (SDIO 2.0 Slave)",
|
||||
"sensor_temperatura": "1 (interno)",
|
||||
"consumo_energia": {
|
||||
"active": "240-360 mA (TX)",
|
||||
"light_sleep": "50-200 µA",
|
||||
"deep_sleep": "10 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 105°C",
|
||||
"temperatura_armazenamento": "-40°C a 150°C",
|
||||
"depuracao": "JTAG integrado via USB (não precisa de sonda externa)",
|
||||
"esp_idf_minimo": "v5.5.2",
|
||||
"arduino_core": "Sim (1 definições de placa no core oficial)",
|
||||
"encapsulamento": "QFN40 (5×5 mm) ou LGA40 (5×5 mm)",
|
||||
"modulos": "ESP32-C61-MINI-1, ESP32-C61-WROOM-1",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-c61_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-c61_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c61/get-started/index.html",
|
||||
"placa": "/placas/esp32-c61.png",
|
||||
"cor": "#0dcaf0"
|
||||
},
|
||||
"ESP32-P4": {
|
||||
"nome_completo": "ESP32-P4",
|
||||
"icone": "⚡",
|
||||
"descricao": "Alto desempenho com processador RISC-V dual-core a 400MHz, aceleradores de IA e ricas interfaces de mídia",
|
||||
"arquitetura": "RISC-V de 32 bits dual-core de alto desempenho (HP) + single-core de baixo consumo (LP)",
|
||||
"nucleos": "2 (Dual-core HP) + 1 (Single-core LP)",
|
||||
"frequencia": "Até 400 MHz (HP, revisão v3.x; 360 MHz na v1.x); LP até 40 MHz",
|
||||
"coprocessador_ulp": "Sim (RISC-V, LP CPU de 40 MHz)",
|
||||
"aceleradores_ia": "Sim (Vector Instructions, aceleradores de IA)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256 com GCM",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Sim (RSA/MPI até 4096 bits)",
|
||||
"ecc": "Sim (P-192, P-256, P-384)",
|
||||
"ecdsa": "Sim (modo determinístico, RFC 6979)",
|
||||
"hmac": "Sim",
|
||||
"assinatura_digital": "Sim",
|
||||
"key_manager": "Sim",
|
||||
"rng": "Sim (TRNG por hardware)",
|
||||
"criptografia_flash": "XTS-AES-128/256",
|
||||
"secure_boot": "V2 (RSA-3072 ou ECDSA)",
|
||||
"protecao_dpa": "Não"
|
||||
},
|
||||
"wifi": "Não",
|
||||
"bluetooth": "Não",
|
||||
"ethernet": "Sim (Ethernet MAC integrado)",
|
||||
"memoria_sram": "768 KB",
|
||||
"memoria_sram_rtc": "32 KB",
|
||||
"memoria_rom": "128 KB (HP ROM) + 16 KB (LP ROM)",
|
||||
"flash_externa": "Até 128 MB via QSPI/Octal SPI",
|
||||
"psram_externa": "16 MB ou 32 MB integrados no encapsulamento (OPI/HPI, 1,8 V)",
|
||||
"gpio": "55",
|
||||
"adc": "2x SAR ADC de 12 bits, até 14 canais",
|
||||
"dac": "Não",
|
||||
"touch": "Sim (sensor de toque capacitivo)",
|
||||
"uart": "6 (5 UART + 1 LP UART)",
|
||||
"spi": "3",
|
||||
"i2c": "3 (2 I2C + 1 LP I2C)",
|
||||
"i2s": "4 (3 I2S + 1 LP I2S)",
|
||||
"pwm": "LED PWM (até 8 canais), Motor PWM (6 canais)",
|
||||
"usb": "USB 2.0 High-Speed OTG + USB 2.0 Full-Speed OTG + USB Serial/JTAG",
|
||||
"mipi_csi": "Interface MIPI CSI para câmera",
|
||||
"mipi_dsi": "Interface MIPI DSI para display",
|
||||
"lcd": "Interface LCD de 8/16/24 bits",
|
||||
"camera": "Interface DVP de 8/16 bits",
|
||||
"sdio": "1 controlador SD/MMC Host (SDHOST)",
|
||||
"sensor_temperatura": "1 (interno)",
|
||||
"consumo_energia": {
|
||||
"active": "15-150 mA (40 a 400 MHz, conforme a carga)",
|
||||
"light_sleep": "75-800 µA",
|
||||
"deep_sleep": "12 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 85°C",
|
||||
"temperatura_armazenamento": "-40°C a 150°C",
|
||||
"depuracao": "JTAG integrado via USB (não precisa de sonda externa)",
|
||||
"esp_idf_minimo": "v5.3",
|
||||
"arduino_core": "Sim (7 definições de placa no core oficial)",
|
||||
"encapsulamento": "QFN104 (10×10 mm)",
|
||||
"modulos": "Sem módulo no catálogo oficial (apenas o chip nu)",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-p4-chip-revision-v1.3_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-p4-chip-revision-v1.3_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/get-started/index.html",
|
||||
"placa": "/placas/esp32-p4.png",
|
||||
"cor": "#ffc107"
|
||||
},
|
||||
"ESP32-H2": {
|
||||
"nome_completo": "ESP32-H2",
|
||||
"icone": "🔋",
|
||||
"descricao": "Focado em ultra-baixo consumo com Bluetooth 6.0, Zigbee e Thread. Mas sem suporte a Wi-Fi",
|
||||
"arquitetura": "RISC-V single-core de 32 bits",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Até 96 MHz",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "Sim (RSA/MPI até 3072 bits)",
|
||||
"ecc": "Sim (P-192, P-256)",
|
||||
"ecdsa": "Sim (modo determinístico, RFC 6979)",
|
||||
"hmac": "Sim",
|
||||
"assinatura_digital": "Sim",
|
||||
"key_manager": "Não",
|
||||
"rng": "Sim (TRNG por hardware)",
|
||||
"criptografia_flash": "XTS-AES-128",
|
||||
"secure_boot": "V2 (RSA-3072 ou ECDSA)",
|
||||
"protecao_dpa": "Sim"
|
||||
},
|
||||
"wifi": "Não",
|
||||
"bluetooth": "Bluetooth 5 (LE) (Bluetooth 5.3 certificado)",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0, Thread 1.4)",
|
||||
"matter": "Sim",
|
||||
"memoria_sram": "320 KB",
|
||||
"memoria_sram_rtc": "4 KB (LP Memory)",
|
||||
"memoria_rom": "128 KB",
|
||||
"flash_externa": "Até 16 MB via QSPI",
|
||||
"psram_externa": "Não",
|
||||
"gpio": "19",
|
||||
"adc": "1x SAR ADC de 12 bits, até 5 canais",
|
||||
"dac": "Não",
|
||||
"touch": "Não",
|
||||
"uart": "2",
|
||||
"spi": "3",
|
||||
"i2c": "2",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (até 6 canais)",
|
||||
"usb": "1 (USB Serial/JTAG)",
|
||||
"sensor_temperatura": "1 (interno)",
|
||||
"consumo_energia": {
|
||||
"active": "24-140 mA (rádio, de -24 a 20 dBm)",
|
||||
"light_sleep": "25-85 µA",
|
||||
"deep_sleep": "7 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 105°C",
|
||||
"temperatura_armazenamento": "-40°C a 150°C",
|
||||
"depuracao": "JTAG integrado via USB (não precisa de sonda externa)",
|
||||
"esp_idf_minimo": "v5.1",
|
||||
"arduino_core": "Sim (3 definições de placa no core oficial)",
|
||||
"encapsulamento": "QFN32 (4×4 mm)",
|
||||
"modulos": "ESP32-H2-MINI-1, ESP32-H2-WROOM-02C",
|
||||
"datasheet": "https://documentation.espressif.com/esp32-h2_datasheet_en.html",
|
||||
"manual_tecnico": "https://documentation.espressif.com/esp32-h2_technical_reference_manual_en.html",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32h2/get-started/index.html",
|
||||
"placa": "/placas/esp32-h2.png",
|
||||
"cor": "#6c757d"
|
||||
},
|
||||
"ESP32-H4": {
|
||||
"nome_completo": "ESP32-H4",
|
||||
"icone": "🛡️",
|
||||
"descricao": "SoC dual-core RISC-V de altíssima eficiência energética com Bluetooth 5.4 LE (LE Audio) e IEEE 802.15.4 para Thread, Zigbee e Matter. Sem Wi-Fi",
|
||||
"status_documentacao": "Documentação preliminar: a Espressif ainda não publicou o datasheet nem o manual técnico do ESP32-H4. Os dados abaixo vêm do anúncio oficial do produto e das definições de hardware (soc_caps) do ESP-IDF, e podem mudar até o lançamento.",
|
||||
"arquitetura": "RISC-V dual-core de 32 bits",
|
||||
"nucleos": "2 (Dual-core)",
|
||||
"frequencia": "Até 96 MHz",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Não",
|
||||
"ecc": "Sim (P-192, P-256, P-384)",
|
||||
"ecdsa": "Sim (modo determinístico, RFC 6979)",
|
||||
"hmac": "Sim",
|
||||
"assinatura_digital": "Não",
|
||||
"key_manager": "Não",
|
||||
"rng": "Sim (TRNG por hardware)",
|
||||
"criptografia_flash": "XTS-AES-128/256",
|
||||
"secure_boot": "Sim no hardware; ainda não habilitado no ESP-IDF",
|
||||
"protecao_dpa": "Não"
|
||||
},
|
||||
"wifi": "Não",
|
||||
"bluetooth": "Bluetooth 5.4 LE (certificado Bluetooth 6.0; LE Audio, canais isócronos BIS/CIS, PAwR, Connection Subrating e Direction Finding AoA/AoD)",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0, Thread 1.4)",
|
||||
"matter": "Sim",
|
||||
"memoria_sram": "384 KB",
|
||||
"memoria_sram_rtc": "Sim (LP SRAM)",
|
||||
"memoria_rom": "128 KB",
|
||||
"flash_externa": "Sim, via QSPI (4 MB integrada no encapsulamento no ESP32-H4HF4)",
|
||||
"psram_externa": "Sim (2 MB integrada no encapsulamento no ESP32-H4HR2)",
|
||||
"gpio": "40",
|
||||
"adc": "1x SAR ADC de 12 bits, até 5 canais",
|
||||
"dac": "Não",
|
||||
"touch": "15 canais capacitivos (versão 3, com waterproof e proximidade)",
|
||||
"uart": "2",
|
||||
"spi": "3",
|
||||
"i2c": "2",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (até 8 canais), Motor PWM (MCPWM)",
|
||||
"can": "1 (CAN 2.0, TWAI®)",
|
||||
"usb": "1 (USB OTG 1.1) + 1 (USB Serial/JTAG)",
|
||||
"sensor_temperatura": "1 (interno)",
|
||||
"consumo_energia": {
|
||||
"active": "Não divulgado (documentação preliminar)"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 105°C",
|
||||
"temperatura_armazenamento": "Não divulgado (documentação preliminar)",
|
||||
"depuracao": "JTAG integrado via USB (não precisa de sonda externa)",
|
||||
"esp_idf_minimo": "v6.0 em preview (sem suporte estável)",
|
||||
"arduino_core": "Ainda não suportado pelo core arduino-esp32",
|
||||
"encapsulamento": "QFN56 (6×6 mm)",
|
||||
"modulos": "ESP32-H4-WROOM-1",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32h4/get-started/index.html",
|
||||
"cor": "#e83e8c"
|
||||
}
|
||||
}
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* Utilitários de rotas e navegação internacionalizada.
|
||||
* Módulo puro (sem 'use client') seguro para Server e Client Components.
|
||||
*/
|
||||
|
||||
// Ponto único de configuração de idiomas ATIVOS.
|
||||
// Para ativar um novo idioma no site, basta adicionar seu código aqui (ex.: ["pt", "en"]).
|
||||
export const ENABLED_LOCALES = ["pt", "en"];
|
||||
|
||||
export const ALL_LOCALES = [
|
||||
{ code: "pt", label: "Português", short: "PT", lang: "pt-BR", og: "pt_BR" },
|
||||
{ code: "en", label: "English", short: "EN", lang: "en", og: "en_US" },
|
||||
{ code: "es", label: "Español", short: "ES", lang: "es-419", og: "es_419" },
|
||||
{ code: "fr", label: "Français", short: "FR", lang: "fr", og: "fr_FR" },
|
||||
{ code: "de", label: "Deutsch", short: "DE", lang: "de", og: "de_DE" },
|
||||
{ code: "zh-CN", label: "简体中文", short: "中", lang: "zh-CN", og: "zh_CN" },
|
||||
];
|
||||
|
||||
export const ALL_LOCALE_CODES = ALL_LOCALES.map((l) => l.code);
|
||||
|
||||
export const LOCALES = ALL_LOCALES.filter((l) => ENABLED_LOCALES.includes(l.code));
|
||||
|
||||
export const CANONICAL_ROUTES = [
|
||||
{
|
||||
id: "series_item",
|
||||
match: /^(?:\/(?:pt|en|es|fr|de|zh-CN))?\/(?:series|serien)\/([^/?#]+)/,
|
||||
getSlug: (loc, key) => (loc === "de" ? `/serien/${key}` : `/series/${key}`),
|
||||
},
|
||||
{
|
||||
id: "frameworks_item",
|
||||
match: /^(?:\/(?:pt|en|es|fr|de|zh-CN))?\/frameworks\/([^/?#]+)/,
|
||||
getSlug: (loc, key) => `/frameworks/${key}`,
|
||||
},
|
||||
{
|
||||
id: "series",
|
||||
match: /^(?:\/(?:pt|en|es|fr|de|zh-CN))?\/(?:series|serien)(?:\/|$)/,
|
||||
getSlug: (loc) => (loc === "de" ? "/serien" : "/series"),
|
||||
},
|
||||
{
|
||||
id: "catalogo",
|
||||
match: /^(?:\/(?:pt|en|es|fr|de|zh-CN))?\/(?:catalogo|catalog|catalogue|katalog)(?:\/|$)/,
|
||||
getSlug: (loc) => {
|
||||
if (loc === "de") return "/katalog";
|
||||
if (loc === "fr") return "/catalogue";
|
||||
if (loc === "en" || loc === "zh-CN") return "/catalog";
|
||||
return "/catalogo";
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "comparacao",
|
||||
match: /^(?:\/(?:pt|en|es|fr|de|zh-CN))?\/(?:comparacao|compare|comparacion|comparaison|vergleich)(?:\/|$)/,
|
||||
getSlug: (loc) => {
|
||||
if (loc === "en" || loc === "zh-CN") return "/compare";
|
||||
if (loc === "es") return "/comparacion";
|
||||
if (loc === "fr") return "/comparaison";
|
||||
if (loc === "de") return "/vergleich";
|
||||
return "/comparacao";
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "componentes",
|
||||
match: /^(?:\/(?:pt|en|es|fr|de|zh-CN))?\/(?:componentes|components|composants|komponenten)(?:\/|$)/,
|
||||
getSlug: (loc) => {
|
||||
if (loc === "en" || loc === "zh-CN") return "/components";
|
||||
if (loc === "fr") return "/composants";
|
||||
if (loc === "de") return "/komponenten";
|
||||
return "/componentes";
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "diagnostico",
|
||||
match: /^(?:\/(?:pt|en|es|fr|de|zh-CN))?\/(?:diagnostico|diagnostics|diagnostic|diagnose)(?:\/|$)/,
|
||||
getSlug: (loc) => {
|
||||
if (loc === "en" || loc === "zh-CN") return "/diagnostics";
|
||||
if (loc === "fr") return "/diagnostic";
|
||||
if (loc === "de") return "/diagnose";
|
||||
return "/diagnostico";
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "frameworks",
|
||||
match: /^(?:\/(?:pt|en|es|fr|de|zh-CN))?\/frameworks(?:\/|$)/,
|
||||
getSlug: () => "/frameworks",
|
||||
},
|
||||
{
|
||||
id: "glossario",
|
||||
match: /^(?:\/(?:pt|en|es|fr|de|zh-CN))?\/(?:glossario|glossary|glosario|glossaire|glossar)(?:\/|$)/,
|
||||
getSlug: (loc) => {
|
||||
if (loc === "en" || loc === "zh-CN") return "/glossary";
|
||||
if (loc === "es") return "/glosario";
|
||||
if (loc === "fr") return "/glossaire";
|
||||
if (loc === "de") return "/glossar";
|
||||
return "/glossario";
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "seletor",
|
||||
match: /^(?:\/(?:pt|en|es|fr|de|zh-CN))?\/(?:seletor|selector|selecteur|auswahl)(?:\/|$)/,
|
||||
getSlug: (loc) => {
|
||||
if (loc === "en" || loc === "es" || loc === "zh-CN") return "/selector";
|
||||
if (loc === "fr") return "/selecteur";
|
||||
if (loc === "de") return "/auswahl";
|
||||
return "/seletor";
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "sobre",
|
||||
match: /^(?:\/(?:pt|en|es|fr|de|zh-CN))?\/(?:sobre|about|acerca|a-propos|ueber-uns)(?:\/|$)/,
|
||||
getSlug: (loc) => {
|
||||
if (loc === "en" || loc === "zh-CN") return "/about";
|
||||
if (loc === "es") return "/acerca";
|
||||
if (loc === "fr") return "/a-propos";
|
||||
if (loc === "de") return "/ueber-uns";
|
||||
return "/sobre";
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "livro",
|
||||
match: /^(?:\/(?:pt|en|es|fr|de|zh-CN))?\/livro(?:\/|$)/,
|
||||
getSlug: (loc) => (loc === "pt" ? "/livro" : ""),
|
||||
},
|
||||
];
|
||||
|
||||
export function getLocalizedHref(pathname, targetLocale) {
|
||||
if (!pathname || pathname === "/") {
|
||||
return `/${targetLocale}`;
|
||||
}
|
||||
|
||||
const [cleanPath, ...queryParts] = pathname.split("?");
|
||||
const query = queryParts.length > 0 ? `?${queryParts.join("?")}` : "";
|
||||
|
||||
for (const loc of ALL_LOCALE_CODES) {
|
||||
if (cleanPath === `/${loc}` || cleanPath === `/${loc}/`) {
|
||||
return `/${targetLocale}${query}`;
|
||||
}
|
||||
}
|
||||
|
||||
for (const route of CANONICAL_ROUTES) {
|
||||
const m = cleanPath.match(route.match);
|
||||
if (m) {
|
||||
const slug = route.getSlug(targetLocale, m[1]);
|
||||
return slug ? `/${targetLocale}${slug}${query}` : `/${targetLocale}${query}`;
|
||||
}
|
||||
}
|
||||
|
||||
return `/${targetLocale}${query}`;
|
||||
}
|
||||
|
||||
export function getPtPath(pathname) {
|
||||
return getLocalizedHref(pathname, "pt");
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { createNavigation } from "next-intl/navigation";
|
||||
import { routing } from "./routing";
|
||||
|
||||
export const { Link, redirect, usePathname, useRouter, getPathname } = createNavigation(routing);
|
||||
@@ -0,0 +1,26 @@
|
||||
import { getRequestConfig } from "next-intl/server";
|
||||
import { hasLocale } from "next-intl";
|
||||
import { routing } from "./routing";
|
||||
|
||||
export default getRequestConfig(async ({ requestLocale }) => {
|
||||
let locale = await requestLocale;
|
||||
if (!locale || !hasLocale(routing.locales, locale)) {
|
||||
locale = routing.defaultLocale;
|
||||
}
|
||||
|
||||
let messages = {};
|
||||
try {
|
||||
messages = (await import(`../messages/${locale}.json`)).default;
|
||||
} catch {
|
||||
try {
|
||||
messages = (await import("../messages/pt.json")).default;
|
||||
} catch {
|
||||
messages = {};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
locale,
|
||||
messages,
|
||||
};
|
||||
});
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
import { defineRouting } from "next-intl/routing";
|
||||
import { ENABLED_LOCALES } from "./links";
|
||||
|
||||
export const routing = defineRouting({
|
||||
locales: ENABLED_LOCALES,
|
||||
defaultLocale: ENABLED_LOCALES.includes("en") ? "en" : (ENABLED_LOCALES[0] || "pt"),
|
||||
localePrefix: "always",
|
||||
pathnames: {
|
||||
"/": "/",
|
||||
"/series": {
|
||||
pt: "/series",
|
||||
en: "/series",
|
||||
es: "/series",
|
||||
fr: "/series",
|
||||
de: "/serien",
|
||||
"zh-CN": "/series",
|
||||
},
|
||||
"/series/[key]": {
|
||||
pt: "/series/[key]",
|
||||
en: "/series/[key]",
|
||||
es: "/series/[key]",
|
||||
fr: "/series/[key]",
|
||||
de: "/serien/[key]",
|
||||
"zh-CN": "/series/[key]",
|
||||
},
|
||||
"/catalogo": {
|
||||
pt: "/catalogo",
|
||||
en: "/catalog",
|
||||
es: "/catalogo",
|
||||
fr: "/catalogue",
|
||||
de: "/katalog",
|
||||
"zh-CN": "/catalog",
|
||||
},
|
||||
"/comparacao": {
|
||||
pt: "/comparacao",
|
||||
en: "/compare",
|
||||
es: "/comparacion",
|
||||
fr: "/comparaison",
|
||||
de: "/vergleich",
|
||||
"zh-CN": "/compare",
|
||||
},
|
||||
"/componentes": {
|
||||
pt: "/componentes",
|
||||
en: "/components",
|
||||
es: "/componentes",
|
||||
fr: "/composants",
|
||||
de: "/komponenten",
|
||||
"zh-CN": "/components",
|
||||
},
|
||||
"/diagnostico": {
|
||||
pt: "/diagnostico",
|
||||
en: "/diagnostics",
|
||||
es: "/diagnostico",
|
||||
fr: "/diagnostic",
|
||||
de: "/diagnose",
|
||||
"zh-CN": "/diagnostics",
|
||||
},
|
||||
"/frameworks": {
|
||||
pt: "/frameworks",
|
||||
en: "/frameworks",
|
||||
es: "/frameworks",
|
||||
fr: "/frameworks",
|
||||
de: "/frameworks",
|
||||
"zh-CN": "/frameworks",
|
||||
},
|
||||
"/frameworks/[key]": {
|
||||
pt: "/frameworks/[key]",
|
||||
en: "/frameworks/[key]",
|
||||
es: "/frameworks/[key]",
|
||||
fr: "/frameworks/[key]",
|
||||
de: "/frameworks/[key]",
|
||||
"zh-CN": "/frameworks/[key]",
|
||||
},
|
||||
"/glossario": {
|
||||
pt: "/glossario",
|
||||
en: "/glossary",
|
||||
es: "/glosario",
|
||||
fr: "/glossaire",
|
||||
de: "/glossar",
|
||||
"zh-CN": "/glossary",
|
||||
},
|
||||
"/seletor": {
|
||||
pt: "/seletor",
|
||||
en: "/selector",
|
||||
es: "/selector",
|
||||
fr: "/selecteur",
|
||||
de: "/auswahl",
|
||||
"zh-CN": "/selector",
|
||||
},
|
||||
"/sobre": {
|
||||
pt: "/sobre",
|
||||
en: "/about",
|
||||
es: "/acerca",
|
||||
fr: "/a-propos",
|
||||
de: "/ueber-uns",
|
||||
"zh-CN": "/about",
|
||||
},
|
||||
"/livro": {
|
||||
pt: "/livro",
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,850 @@
|
||||
/**
|
||||
* Official Curated Database: ESP Component Registry & IDF Component Manager
|
||||
*
|
||||
* The ESP Component Registry (https://components.espressif.com) is the central
|
||||
* distribution ecosystem for modular libraries targeting ESP-IDF v4.4+ / v5.x+.
|
||||
*/
|
||||
|
||||
export const CATEGORIAS_COMPONENTES = [
|
||||
{
|
||||
id: "todos",
|
||||
nome: "All Components",
|
||||
icone: "Layers",
|
||||
descricao: "Explore the curated catalog of libraries and drivers"
|
||||
},
|
||||
{
|
||||
id: "ui_display",
|
||||
nome: "UI, Displays & Graphics",
|
||||
icone: "Monitor",
|
||||
descricao: "Graphics libraries (LVGL), LCD/OLED display drivers, touch controllers and decoders"
|
||||
},
|
||||
{
|
||||
id: "cloud_conectividade",
|
||||
nome: "Cloud & Connectivity",
|
||||
icone: "Cloud",
|
||||
descricao: "ESP RainMaker, AWS IoT, MQTT, WebSockets, Mesh-Lite and ESP-Hosted coprocessing"
|
||||
},
|
||||
{
|
||||
id: "audio_voz_ia",
|
||||
nome: "Audio, Voice & AI",
|
||||
icone: "Brain",
|
||||
descricao: "ESP-SR speech recognition, DSP processing, audio codecs, DVP cameras and TinyML"
|
||||
},
|
||||
{
|
||||
id: "smart_home_mesh",
|
||||
nome: "Smart Home & Mesh",
|
||||
icone: "Home",
|
||||
descricao: "Matter SDK, Zigbee 3.0 (ZBOSS) stacks, Thread and ESP-NOW networks"
|
||||
},
|
||||
{
|
||||
id: "drivers_perifericos",
|
||||
nome: "Drivers & Sensors",
|
||||
icone: "Cpu",
|
||||
descricao: "Buttons, encoders, RGB LEDs, Ethernet (W5500/CH390), native USB and environmental/IMU sensors"
|
||||
},
|
||||
{
|
||||
id: "bsp_placas",
|
||||
nome: "BSPs (Board Support Packages)",
|
||||
icone: "CircuitBoard",
|
||||
descricao: "Direct board support packages for official boards like ESP-BOX-3, Korvo, EYE and M5Stack"
|
||||
},
|
||||
{
|
||||
id: "sistema_utilitarios",
|
||||
nome: "System & Utilities",
|
||||
icone: "Wrench",
|
||||
descricao: "LittleFS file systems, modern C++ wrappers, CBOR and networking utilities"
|
||||
}
|
||||
];
|
||||
|
||||
export const COMPONENTES_REGISTRY = [
|
||||
// ==========================================
|
||||
// 1. UI, Displays & Graphics
|
||||
// ==========================================
|
||||
{
|
||||
id: "espressif-esp_lvgl_port",
|
||||
namespace: "espressif",
|
||||
name: "esp_lvgl_port",
|
||||
versao: "^2.4.0",
|
||||
categoria: "ui_display",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP LVGL Port",
|
||||
descricao: "Official thread-safe LVGL (Light and Versatile Graphics Library) port for ESP-IDF with hardware acceleration and multi-display support.",
|
||||
tags: ["LVGL", "GUI", "Display", "Touch", "HMI"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-P4", "ESP32-C3", "ESP32-C6"],
|
||||
dependenciasSugeridas: ["lvgl/lvgl^9.1.0"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_lvgl_port",
|
||||
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/components/esp_lvgl_port",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_lvgl_port: "^2.4.0"
|
||||
lvgl/lvgl: "^9.1.0"`
|
||||
},
|
||||
{
|
||||
id: "lvgl-lvgl",
|
||||
namespace: "lvgl",
|
||||
name: "lvgl",
|
||||
versao: "^9.1.0",
|
||||
categoria: "ui_display",
|
||||
oficial: false,
|
||||
popular: true,
|
||||
titulo: "LVGL Graphics Library Core",
|
||||
descricao: "Most popular open-source C graphics library for embedded systems. Provides rich widgets, smooth animations, and modern layout support.",
|
||||
tags: ["LVGL 9", "Graphics", "Widgets", "GUI", "Embedded UI"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-P4", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/lvgl/lvgl",
|
||||
urlRepo: "https://github.com/lvgl/lvgl",
|
||||
exemploYaml: `dependencies:
|
||||
lvgl/lvgl: "^9.1.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp32_display_panel",
|
||||
namespace: "espressif",
|
||||
name: "esp32_display_panel",
|
||||
versao: "^0.2.0",
|
||||
categoria: "ui_display",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP32 Display Panel Driver",
|
||||
descricao: "Unified driver for LCD controllers (RGB, SPI, QSPI, MIPI-DSI) and capacitive touch panels tailored for ESP32-S3 and ESP32-P4.",
|
||||
tags: ["LCD", "MIPI-DSI", "QSPI", "Touch", "ST7789", "ILI9341"],
|
||||
chips: ["ESP32-S3", "ESP32-P4", "ESP32-S2", "ESP32"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp32_display_panel",
|
||||
urlRepo: "https://github.com/esp-arduino-libs/ESP32_Display_Panel",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp32_display_panel: "^0.2.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_lcd_touch",
|
||||
namespace: "espressif",
|
||||
name: "esp_lcd_touch",
|
||||
versao: "^1.1.2",
|
||||
categoria: "ui_display",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP LCD Touch Framework",
|
||||
descricao: "Core touch panel abstraction component for LCDs. Supports coordinate calibration, multi-touch tracking, and direct LVGL integration.",
|
||||
tags: ["Touchscreen", "Capacitive", "Resistive", "I2C Touch", "Coordinates"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-P4", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_lcd_touch",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/display/touch_panel/esp_lcd_touch",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_lcd_touch: "^1.1.2"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_lcd_touch_gt911",
|
||||
namespace: "espressif",
|
||||
name: "esp_lcd_touch_gt911",
|
||||
versao: "^1.1.2",
|
||||
categoria: "ui_display",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "GT911 Capacitive Touch Driver",
|
||||
descricao: "Specialized I2C driver for Goodix GT911 capacitive touch controllers, widely used in 4.3\", 5.0\", and 7.0\" LCD modules.",
|
||||
tags: ["GT911", "Goodix", "Touch I2C", "Capacitive"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-S2"],
|
||||
dependenciasSugeridas: ["espressif/esp_lcd_touch^1.1.2"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_lcd_touch_gt911",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/display/touch_panel/esp_lcd_touch_gt911",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_lcd_touch_gt911: "^1.1.2"
|
||||
espressif/esp_lcd_touch: "^1.1.2"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_lcd_touch_ft5x06",
|
||||
namespace: "espressif",
|
||||
name: "esp_lcd_touch_ft5x06",
|
||||
versao: "^1.1.2",
|
||||
categoria: "ui_display",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "FocalTech FT5x06 / FT6x36 Touch Driver",
|
||||
descricao: "Capacitive touch panel driver for FocalTech controllers commonly integrated into maker displays and development modules.",
|
||||
tags: ["FT6236", "FT5406", "Touchscreen", "I2C"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3"],
|
||||
dependenciasSugeridas: ["espressif/esp_lcd_touch^1.1.2"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_lcd_touch_ft5x06",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/display/touch_panel/esp_lcd_touch_ft5x06",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_lcd_touch_ft5x06: "^1.1.2"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_jpeg",
|
||||
namespace: "espressif",
|
||||
name: "esp_jpeg",
|
||||
versao: "^1.0.5",
|
||||
categoria: "ui_display",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP JPEG Decoder (TJpgDec)",
|
||||
descricao: "High-speed JPEG decoder and encoder optimized with assembly and SIMD instructions for rapid rendering on RGB and SPI displays.",
|
||||
tags: ["JPEG", "TJpgDec", "Image Decoder", "Display", "SIMD"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_jpeg",
|
||||
urlRepo: "https://github.com/espressif/esp-jpeg",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_jpeg: "^1.0.5"`
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// 2. Cloud & Connectivity
|
||||
// ==========================================
|
||||
{
|
||||
id: "espressif-esp_rainmaker",
|
||||
namespace: "espressif",
|
||||
name: "esp_rainmaker",
|
||||
versao: "^1.4.0",
|
||||
categoria: "cloud_conectividade",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP RainMaker Agent",
|
||||
descricao: "Official firmware agent for Espressif's serverless AIoT cloud platform. Handles dynamic data modeling, OTA, and mobile app integration.",
|
||||
tags: ["RainMaker", "AWS IoT", "Cloud", "App Control", "Zero-Code-Backend"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
|
||||
dependenciasSugeridas: ["espressif/net_connect^0.1.0"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_rainmaker",
|
||||
urlRepo: "https://github.com/espressif/esp-rainmaker",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_rainmaker: "^1.4.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-mesh_lite",
|
||||
namespace: "espressif",
|
||||
name: "mesh_lite",
|
||||
versao: "^1.0.2",
|
||||
categoria: "cloud_conectividade",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP Mesh-Lite Network Stack",
|
||||
descricao: "Lightweight Wi-Fi mesh network where every node maintains IP connectivity, communicating directly with local servers or cloud platforms.",
|
||||
tags: ["Mesh-Lite", "Wi-Fi Mesh", "IoT Network", "No-Gateway"],
|
||||
chips: ["ESP32", "ESP32-C3", "ESP32-S3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/mesh_lite",
|
||||
urlRepo: "https://github.com/espressif/esp-mesh-lite",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/mesh_lite: "^1.0.2"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_modbus",
|
||||
namespace: "espressif",
|
||||
name: "esp_modbus",
|
||||
versao: "^2.0.0",
|
||||
categoria: "cloud_conectividade",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP-Modbus Industrial Stack",
|
||||
descricao: "Complete industrial Modbus stack (Master/Slave) over Serial RS485 (RTU/ASCII) and Ethernet/Wi-Fi (TCP) for PLC and SCADA integration.",
|
||||
tags: ["Modbus RTU", "Modbus TCP", "RS485", "PLC", "Industrial IoT"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_modbus",
|
||||
urlRepo: "https://github.com/espressif/esp-modbus",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_modbus: "^2.0.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-net_connect",
|
||||
namespace: "espressif",
|
||||
name: "net_connect",
|
||||
versao: "^0.1.1",
|
||||
categoria: "cloud_conectividade",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "Network Connect Helper",
|
||||
descricao: "Unified helper module to establish and monitor Wi-Fi, Ethernet, and Thread connections with automatic reconnection and event callbacks.",
|
||||
tags: ["Wi-Fi Connect", "Ethernet", "Thread", "Network Manager"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/net_connect",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/net_connect: "^0.1.1"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_hosted",
|
||||
namespace: "espressif",
|
||||
name: "esp_hosted",
|
||||
versao: "^2.0.0",
|
||||
categoria: "cloud_conectividade",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "ESP-Hosted Network Coprocessor",
|
||||
descricao: "Turns the ESP32 into a Wi-Fi and Bluetooth wireless network card for external Linux hosts (Raspberry Pi) or MCUs via SPI/SDIO/UART.",
|
||||
tags: ["Network Coprocessor", "SDIO", "SPI Slave", "Linux Wireless"],
|
||||
chips: ["ESP32", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_hosted",
|
||||
urlRepo: "https://github.com/espressif/esp-hosted",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_hosted: "^2.0.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp-now",
|
||||
namespace: "espressif",
|
||||
name: "esp-now",
|
||||
versao: "^2.5.0",
|
||||
categoria: "cloud_conectividade",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP-NOW Connectionless Protocol",
|
||||
descricao: "Direct peer-to-peer wireless protocol by Espressif enabling ultra-fast, low-power communication without a Wi-Fi router.",
|
||||
tags: ["ESP-NOW", "P2P", "Low Power", "Quick Pairing", "Sub-10ms"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C2", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-now",
|
||||
urlRepo: "https://github.com/espressif/esp-now",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-now: "^2.5.0"`
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// 3. Audio, Voice & AI
|
||||
// ==========================================
|
||||
{
|
||||
id: "espressif-esp-sr",
|
||||
namespace: "espressif",
|
||||
name: "esp-sr",
|
||||
versao: "^2.0.0",
|
||||
categoria: "audio_voz_ia",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP-SR Speech Recognition Framework",
|
||||
descricao: "Complete offline voice recognition framework: wake word detection (WakeNet), command recognition (MultiNet), acoustic echo cancellation (AEC), and beamforming.",
|
||||
tags: ["WakeNet", "MultiNet", "Voice Assistant", "AEC", "Offline AI", "Audio DSP"],
|
||||
chips: ["ESP32-S3", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-sr",
|
||||
urlRepo: "https://github.com/espressif/esp-sr",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-sr: "^2.0.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_codec_dev",
|
||||
namespace: "espressif",
|
||||
name: "esp_codec_dev",
|
||||
versao: "^1.3.0",
|
||||
categoria: "audio_voz_ia",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP Audio Codec Device Driver",
|
||||
descricao: "Unified hardware abstraction layer for audio DACs, ADCs, and Codecs (ES8311, ES8388, TAS5805M, Everest) communicating over I2S and I2C.",
|
||||
tags: ["Audio Codec", "DAC", "I2S", "Microphone", "Speaker", "ES8311"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-C3"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_codec_dev",
|
||||
urlRepo: "https://github.com/espressif/esp-codec-dev",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_codec_dev: "^1.3.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-es8311",
|
||||
namespace: "espressif",
|
||||
name: "es8311",
|
||||
versao: "^0.2.0",
|
||||
categoria: "audio_voz_ia",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "Everest ES8311 Low-Power Audio Codec Driver",
|
||||
descricao: "Low-power mono audio codec driver with analog microphone input and class-D speaker output, standard on ESP-BOX and LyraT boards.",
|
||||
tags: ["ES8311", "Mono Codec", "Microphone Preamp", "ESP-BOX"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-S2"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/es8311",
|
||||
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/components/es8311",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/es8311: "^0.2.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp32-camera",
|
||||
namespace: "espressif",
|
||||
name: "esp32-camera",
|
||||
versao: "^2.0.9",
|
||||
categoria: "audio_voz_ia",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP32 Camera Driver",
|
||||
descricao: "Official driver for DVP CMOS camera sensors (OV2640, OV3660, OV5640, GC0308). Delivers DMA-accelerated JPEG and RGB565 streaming.",
|
||||
tags: ["Camera", "OV2640", "OV5640", "DVP", "Video Streaming", "ESP32-CAM"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-S2"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp32-camera",
|
||||
urlRepo: "https://github.com/espressif/esp32-camera",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp32-camera: "^2.0.9"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp-dsp",
|
||||
namespace: "espressif",
|
||||
name: "esp-dsp",
|
||||
versao: "^1.5.0",
|
||||
categoria: "audio_voz_ia",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP-DSP Digital Signal Processing Library",
|
||||
descricao: "Digital signal processing library with vector-accelerated FFTs, IIR/FIR filtering, and matrix math for audio and vibration analysis.",
|
||||
tags: ["DSP", "FFT", "Matrix", "FIR Filter", "IIR Filter", "Assembly SIMD"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-dsp",
|
||||
urlRepo: "https://github.com/espressif/esp-dsp",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-dsp: "^1.5.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp-nn",
|
||||
namespace: "espressif",
|
||||
name: "esp-nn",
|
||||
versao: "^1.1.0",
|
||||
categoria: "audio_voz_ia",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "ESP-NN Neural Network Kernel Kernels",
|
||||
descricao: "Optimized neural network convolution, depthwise-conv, and activation kernels for TensorFlow Lite for Microcontrollers and TinyML models.",
|
||||
tags: ["Neural Network", "TinyML", "TFLite Micro", "Vector Math", "Convolution"],
|
||||
chips: ["ESP32-S3", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-nn",
|
||||
urlRepo: "https://github.com/espressif/esp-nn",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-nn: "^1.1.0"`
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// 4. Smart Home & Mesh
|
||||
// ==========================================
|
||||
{
|
||||
id: "espressif-esp-matter",
|
||||
namespace: "espressif",
|
||||
name: "esp-matter",
|
||||
versao: "^1.3.0",
|
||||
categoria: "smart_home_mesh",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP-Matter SDK",
|
||||
descricao: "Official Matter SDK by Espressif built on Connected Home IP. Create Matter over Wi-Fi and Matter over Thread smart devices with Apple Home, Alexa, and Google Home interoperability.",
|
||||
tags: ["Matter", "CHIP", "Thread", "Smart Home", "Apple Home", "Google Home"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-H2"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-matter",
|
||||
urlRepo: "https://github.com/espressif/esp-matter",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-matter: "^1.3.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp-zigbee-lib",
|
||||
namespace: "espressif",
|
||||
name: "esp-zigbee-lib",
|
||||
versao: "^1.4.0",
|
||||
categoria: "smart_home_mesh",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP-Zigbee 3.0 Stack Library",
|
||||
descricao: "Certified Zigbee 3.0 (ZBOSS) stack supporting Coordinator, Router, and End Device roles on IEEE 802.15.4 radios.",
|
||||
tags: ["Zigbee 3.0", "ZBOSS", "802.15.4", "Coordinator", "Router", "End Device"],
|
||||
chips: ["ESP32-C6", "ESP32-H2"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-zigbee-lib",
|
||||
urlRepo: "https://github.com/espressif/esp-zigbee-sdk",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-zigbee-lib: "^1.4.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_rcp_update",
|
||||
namespace: "espressif",
|
||||
name: "esp_rcp_update",
|
||||
versao: "^0.1.2",
|
||||
categoria: "smart_home_mesh",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "Thread Radio Co-Processor (RCP) Update",
|
||||
descricao: "Firmware manager and updater for Thread RCP architectures, used in OpenThread Border Routers (OTBR) combining ESP32-S3 and ESP32-H2.",
|
||||
tags: ["OpenThread", "RCP", "Border Router", "OTBR", "802.15.4"],
|
||||
chips: ["ESP32-S3", "ESP32-C6", "ESP32-H2"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_rcp_update",
|
||||
urlRepo: "https://github.com/espressif/esp-thread-lib",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_rcp_update: "^0.1.2"`
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// 5. Drivers & Sensors
|
||||
// ==========================================
|
||||
{
|
||||
id: "espressif-led_indicator",
|
||||
namespace: "espressif",
|
||||
name: "led_indicator",
|
||||
versao: "^0.9.3",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "LED Indicator & Blink Pattern Driver",
|
||||
descricao: "Visual status engine managing simple and RGB LEDs with non-blocking blink sequences, breathing effects, and priority queues.",
|
||||
tags: ["LED Blink", "RGB Status", "Breathing Effect", "User Feedback"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C2", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/led_indicator",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/led/led_indicator",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/led_indicator: "^0.9.3"`
|
||||
},
|
||||
{
|
||||
id: "espressif-button",
|
||||
namespace: "espressif",
|
||||
name: "button",
|
||||
versao: "^3.3.0",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "Advanced Button & Event Handler (IoT Button)",
|
||||
descricao: "Robust debounce and event engine for physical buttons: detects single-click, double-click, long-press, repeat events, and ADC resistor ladder keys.",
|
||||
tags: ["Debounce", "Double Click", "Long Press", "ADC Button", "GPIO Key"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/button",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/button",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/button: "^3.3.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-led_strip",
|
||||
namespace: "espressif",
|
||||
name: "led_strip",
|
||||
versao: "^2.5.3",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "Addressable RGB LED Strip Driver (RMT / SPI)",
|
||||
descricao: "Official driver for addressable RGB/RGBW LED strips (WS2812B, SK6812, APA102) utilizing hardware RMT or SPI peripherals without CPU overhead.",
|
||||
tags: ["WS2812", "NeoPixel", "SK6812", "RMT", "RGB Strip", "Addressable LED"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/led_strip",
|
||||
urlRepo: "https://github.com/espressif/idf-extra-components/tree/master/led_strip",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/led_strip: "^2.5.3"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_tinyusb",
|
||||
namespace: "espressif",
|
||||
name: "esp_tinyusb",
|
||||
versao: "^1.4.5",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "TinyUSB Hardware Native USB Stack",
|
||||
descricao: "Complete native USB stack (Device and Host): emulates HID (Keyboard/Mouse), CDC (Virtual Serial), MSC (Mass Storage Flash Drive), and MIDI.",
|
||||
tags: ["USB OTG", "TinyUSB", "USB CDC", "USB HID", "USB Flash Drive", "Mass Storage"],
|
||||
chips: ["ESP32-S2", "ESP32-S3", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_tinyusb",
|
||||
urlRepo: "https://github.com/espressif/esp-tinyusb",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_tinyusb: "^1.4.5"`
|
||||
},
|
||||
{
|
||||
id: "espressif-w5500",
|
||||
namespace: "espressif",
|
||||
name: "w5500",
|
||||
versao: "^1.1.0",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "WIZnet W5500 SPI Ethernet Driver",
|
||||
descricao: "Official driver for WIZnet W5500 SPI Ethernet controllers, integrating seamlessly into ESP-IDF's lwIP network stack with high throughput.",
|
||||
tags: ["Ethernet", "W5500", "SPI LAN", "lwIP", "Wired Network"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/w5500",
|
||||
urlRepo: "https://github.com/espressif/esp-eth-drivers/tree/master/w5500",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/w5500: "^1.1.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-ch390",
|
||||
namespace: "espressif",
|
||||
name: "ch390",
|
||||
versao: "^0.1.2",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "WCH CH390 SPI 10/100M Ethernet Driver",
|
||||
descricao: "Cost-effective 10/100Mbps Ethernet MAC/PHY driver for WCH CH390 chips communicating over high-speed SPI.",
|
||||
tags: ["CH390", "Ethernet SPI", "WCH", "Cost Effective", "lwIP"],
|
||||
chips: ["ESP32", "ESP32-C3", "ESP32-S3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/ch390",
|
||||
urlRepo: "https://github.com/espressif/esp-eth-drivers",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/ch390: "^0.1.2"`
|
||||
},
|
||||
{
|
||||
id: "espressif-usb_host_uvc",
|
||||
namespace: "espressif",
|
||||
name: "usb_host_uvc",
|
||||
versao: "^1.0.3",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "USB Host UVC Video Camera Driver",
|
||||
descricao: "Native USB Host driver allowing connection to standard USB UVC webcams directly from ESP32-S2/S3/P4.",
|
||||
tags: ["USB Host", "UVC", "Webcam USB", "Video Streaming"],
|
||||
chips: ["ESP32-S2", "ESP32-S3", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/usb_host_uvc",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/usb_host_uvc: "^1.0.3"`
|
||||
},
|
||||
{
|
||||
id: "espressif-sensor_hub",
|
||||
namespace: "espressif",
|
||||
name: "sensor_hub",
|
||||
versao: "^0.5.2",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "Sensor Hub Data Acquisition Architecture",
|
||||
descricao: "Modular sensor abstraction framework with event-driven sampling, buffer management, and automatic calibration for environmental and IMU sensors.",
|
||||
tags: ["Sensor Hub", "I2C Sensor", "Sampling Event", "IMU"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/sensor_hub",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/sensors/sensor_hub",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/sensor_hub: "^0.5.2"`
|
||||
},
|
||||
{
|
||||
id: "espressif-bmi270_sensor",
|
||||
namespace: "espressif",
|
||||
name: "bmi270_sensor",
|
||||
versao: "^0.1.2",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "Bosch BMI270 6-Axis IMU Sensor Driver",
|
||||
descricao: "Driver for Bosch BMI270 6-axis ultra-low-power IMU (accelerometer and gyroscope) featuring built-in step counter and gesture detection.",
|
||||
tags: ["BMI270", "IMU 6-Axis", "Accelerometer", "Gyroscope", "Bosch"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/bmi270_sensor",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/bmi270_sensor: "^0.1.2"`
|
||||
},
|
||||
{
|
||||
id: "espressif-ds18b20",
|
||||
namespace: "espressif",
|
||||
name: "ds18b20",
|
||||
versao: "^0.1.1",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "Dallas DS18B20 1-Wire Temperature Sensor",
|
||||
descricao: "RMT-accelerated 1-Wire temperature sensor driver providing non-blocking precision multi-sensor reading on a single bus line.",
|
||||
tags: ["DS18B20", "1-Wire", "Temperature", "RMT", "Waterproof"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/ds18b20",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/ds18b20: "^0.1.1"`
|
||||
},
|
||||
{
|
||||
id: "esp-idf-lib-scd4x",
|
||||
namespace: "esp-idf-lib",
|
||||
name: "scd4x",
|
||||
versao: "^1.0.0",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: false,
|
||||
popular: true,
|
||||
titulo: "Sensirion SCD40 / SCD41 CO2 Photoacoustic Sensor",
|
||||
descricao: "Driver for Sensirion SCD40/SCD41 true CO2 sensors with integrated relative humidity and ambient temperature measurements.",
|
||||
tags: ["SCD40", "SCD41", "CO2 Sensor", "Air Quality", "I2C Sensirion"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/esp-idf-lib/scd4x",
|
||||
urlRepo: "https://github.com/UncleRus/esp-idf-lib",
|
||||
exemploYaml: `dependencies:
|
||||
esp-idf-lib/scd4x: "^1.0.0"`
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// 6. BSPs (Board Support Packages)
|
||||
// ==========================================
|
||||
{
|
||||
id: "espressif-esp-box-3",
|
||||
namespace: "espressif",
|
||||
name: "esp-box-3",
|
||||
versao: "^1.3.1",
|
||||
categoria: "bsp_placas",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP32-S3-BOX-3 Board Support Package (BSP)",
|
||||
descricao: "Comprehensive BSP for the ESP-BOX-3 development kit: configures display, capacitive touch, ES8311 codec, dual microphones, sensor dock, and PCIe connector out-of-the-box.",
|
||||
tags: ["ESP-BOX-3", "ESP32-S3", "BSP", "Touch LCD", "Voice AI", "Sensors"],
|
||||
chips: ["ESP32-S3"],
|
||||
dependenciasSugeridas: ["espressif/esp_lvgl_port^2.4.0"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-box-3",
|
||||
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/bsp/esp-box-3",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-box-3: "^1.3.1"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp32_s3_korvo_2",
|
||||
namespace: "espressif",
|
||||
name: "esp32_s3_korvo_2",
|
||||
versao: "^1.0.2",
|
||||
categoria: "bsp_placas",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "ESP32-S3-Korvo-2 Audio Development Board BSP",
|
||||
descricao: "Official BSP for the multi-microphone Korvo-2 board: initializes dual ES7210 ADCs, ES8311 DAC, far-field beamforming, and AEC processing.",
|
||||
tags: ["Korvo-2", "Audio Board", "Microphone Array", "AEC", "ESP-ADF"],
|
||||
chips: ["ESP32-S3"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp32_s3_korvo_2",
|
||||
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_korvo_2",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp32_s3_korvo_2: "^1.0.2"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp32_s3_eye",
|
||||
namespace: "espressif",
|
||||
name: "esp32_s3_eye",
|
||||
versao: "^1.1.0",
|
||||
categoria: "bsp_placas",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP32-S3-EYE Vision AI Board BSP",
|
||||
descricao: "BSP for the ESP32-S3-EYE computer vision kit: auto-initializes the OV2640 camera, 1.3\" SPI display, microphone, and on-board digital sensors.",
|
||||
tags: ["S3-EYE", "Camera AI", "OV2640", "Face Recognition", "ESP-WHO"],
|
||||
chips: ["ESP32-S3"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp32_s3_eye",
|
||||
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_eye",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp32_s3_eye: "^1.1.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-m5stack_core_s3",
|
||||
namespace: "espressif",
|
||||
name: "m5stack_core_s3",
|
||||
versao: "^0.2.0",
|
||||
categoria: "bsp_placas",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "M5Stack CoreS3 BSP for ESP-IDF",
|
||||
descricao: "BSP for the popular M5Stack CoreS3: configures ILI9342C display, FT6336 touch controller, AXP2101 power management PMIC, camera, and dual microphones.",
|
||||
tags: ["M5Stack", "CoreS3", "AXP2101", "ILI9342C", "Modular IoT"],
|
||||
chips: ["ESP32-S3"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/m5stack_core_s3",
|
||||
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/bsp/m5stack_core_s3",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/m5stack_core_s3: "^0.2.0"`
|
||||
},
|
||||
{
|
||||
id: "waveshare-esp32_p4_wifi6_touch_lcd_7b",
|
||||
namespace: "waveshare",
|
||||
name: "esp32_p4_wifi6_touch_lcd_7b",
|
||||
versao: "^0.1.0",
|
||||
categoria: "bsp_placas",
|
||||
oficial: false,
|
||||
popular: true,
|
||||
titulo: "Waveshare ESP32-P4 7-inch Touch LCD BSP",
|
||||
descricao: "Support package for Waveshare's flagship ESP32-P4 board featuring 7.0\" MIPI-DSI (1024x600) display, GT911 touch controller, and Wi-Fi 6 coprocessor.",
|
||||
tags: ["ESP32-P4", "MIPI-DSI", "Waveshare 7B", "1024x600", "High Performance HMI"],
|
||||
chips: ["ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/waveshare/esp32_p4_wifi6_touch_lcd_7b",
|
||||
urlRepo: "https://github.com/waveshare/esp32-p4-bsp",
|
||||
exemploYaml: `dependencies:
|
||||
waveshare/esp32_p4_wifi6_touch_lcd_7b: "^0.1.0"`
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// 7. System & Utilities
|
||||
// ==========================================
|
||||
{
|
||||
id: "joltwallet-littlefs",
|
||||
namespace: "joltwallet",
|
||||
name: "littlefs",
|
||||
versao: "^1.14.8",
|
||||
categoria: "sistema_utilitarios",
|
||||
oficial: false,
|
||||
popular: true,
|
||||
titulo: "LittleFS Resilient Embedded File System",
|
||||
descricao: "Power-failure resilient file system designed for microcontrollers with wear leveling, zero RAM leaks on unexpected resets, and high speed.",
|
||||
tags: ["LittleFS", "File System", "VFS", "Flash Wear Leveling", "Power Safe"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C2", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/joltwallet/littlefs",
|
||||
urlRepo: "https://github.com/joltwallet/esp_littlefs",
|
||||
exemploYaml: `dependencies:
|
||||
joltwallet/littlefs: "^1.14.8"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp-idf-cxx",
|
||||
namespace: "espressif",
|
||||
name: "esp-idf-cxx",
|
||||
versao: "^0.2.1",
|
||||
categoria: "sistema_utilitarios",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "Modern C++ (C++17/20/23) ESP-IDF Wrappers",
|
||||
descricao: "Modern type-safe C++ wrappers for ESP-IDF primitives: RAII locks, exceptions, tasks, queues, GPIOs, and I2C/SPI buses.",
|
||||
tags: ["C++20", "C++17", "RAII", "Object Oriented", "Type Safe"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-idf-cxx",
|
||||
urlRepo: "https://github.com/espressif/esp-idf-cxx",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-idf-cxx: "^0.2.1"`
|
||||
},
|
||||
{
|
||||
id: "espressif-cbor",
|
||||
namespace: "espressif",
|
||||
name: "cbor",
|
||||
versao: "^0.6.0",
|
||||
categoria: "sistema_utilitarios",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "TinyCBOR Binary Serialization Library",
|
||||
descricao: "Compact binary object serialization library (RFC 8949) offering lightweight alternative to JSON for low-bandwidth constrained IoT communication.",
|
||||
tags: ["CBOR", "Binary JSON", "Compact Serialization", "RFC 8949", "CoAP"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/cbor",
|
||||
urlRepo: "https://github.com/intel/tinycbor",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/cbor: "^0.6.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_websocket_client",
|
||||
namespace: "espressif",
|
||||
name: "esp_websocket_client",
|
||||
versao: "^1.2.3",
|
||||
categoria: "sistema_utilitarios",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP WebSocket Client (WS / WSS)",
|
||||
descricao: "Full-duplex real-time WebSocket client supporting text and binary frames over secure TLS connections (WSS) and automatic reconnections.",
|
||||
tags: ["WebSocket", "WSS", "TLS", "Real-Time", "Full Duplex"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_websocket_client",
|
||||
urlRepo: "https://github.com/espressif/esp-protocols/tree/master/components/esp_websocket_client",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_websocket_client: "^1.2.3"`
|
||||
}
|
||||
];
|
||||
|
||||
export const GUIA_COMPONENT_MANAGER = {
|
||||
titulo: "How to Use the ESP Component Registry in ESP-IDF",
|
||||
resumo: "Starting with ESP-IDF v4.4 and established in v5.x+, Espressif adopted a modular package architecture managed by the IDF Component Manager. Forget complex git submodules: declare libraries in your project's idf_component.yml manifest file.",
|
||||
vantagens: [
|
||||
{
|
||||
titulo: "Automatic and Decoupled Installation",
|
||||
descricao: "The build system downloads, compiles, and manages library versions automatically during 'idf.py build' or 'idf.py reconfigure'."
|
||||
},
|
||||
{
|
||||
titulo: "Strict Semantic Versioning",
|
||||
descricao: "Control exactly when to update using version operators (^ for minor compatibility, ~ for patches, or exact fixed versions)."
|
||||
},
|
||||
{
|
||||
titulo: "Lighter and Cleaner Projects",
|
||||
descricao: "Your project repository stays clean, without embedding third-party code in your Git history."
|
||||
},
|
||||
{
|
||||
titulo: "Enterprise or Community Sharing",
|
||||
descricao: "Publish your own components to the public Espressif cloud registry or your company's private internal registries."
|
||||
}
|
||||
],
|
||||
comandosCli: [
|
||||
{
|
||||
comando: "idf.py add-dependency \"namespace/component^version\"",
|
||||
exemplo: "idf.py add-dependency \"espressif/esp_lvgl_port^2.4.0\"",
|
||||
explicacao: "Automatically creates or updates the 'main/idf_component.yml' file by adding the specified dependency."
|
||||
},
|
||||
{
|
||||
comando: "idf.py reconfigure",
|
||||
exemplo: "idf.py reconfigure",
|
||||
explicacao: "Forces CMake and Component Manager to re-resolve the dependency tree and download pending packages."
|
||||
},
|
||||
{
|
||||
comando: "compote component upload --name <component_name> --namespace <your_org>",
|
||||
exemplo: "compote component upload --name my_sensor_driver --namespace myteam",
|
||||
explicacao: "Publishes your open-source or proprietary component to the ESP Component Registry using the official Compote CLI tool."
|
||||
}
|
||||
],
|
||||
sintaxeManifesto: "# Typical file structure: main/idf_component.yml\ndependencies:\n # Download from official Espressif registry\n espressif/esp_lvgl_port: \"^2.4.0\"\n espressif/button: \"~3.4.0\"\n \n # Exact version\n espressif/led_indicator: \"1.2.0\"\n \n # Community dependency\n joltwallet/littlefs: \"^1.14.8\"\n \n # Local disk dependency (optional)\n # my_local_driver:\n # path: \"../../components/my_driver\""
|
||||
};
|
||||
|
||||
@@ -0,0 +1,722 @@
|
||||
/**
|
||||
* Structured Database for ESP32 Troubleshooting, Common Errors, and Diagnostics Guide.
|
||||
* Covers 6 technical categories with root causes, best practices vs workarounds, and code examples
|
||||
* in Arduino C++, ESP-IDF (C), and MicroPython.
|
||||
*/
|
||||
|
||||
export const categoriasDiagnostico = [
|
||||
{
|
||||
id: "alimentacao",
|
||||
nome: "Power & Hardware",
|
||||
icone: "Zap",
|
||||
cor: "amber",
|
||||
descricao: "Voltage drops caused by Wi-Fi/BLE RF spikes, conflicting strapping pins, electromagnetic noise, and LDO issues.",
|
||||
},
|
||||
{
|
||||
id: "cpu-panics",
|
||||
nome: "CPU Panics & Guru Meditation",
|
||||
icone: "Cpu",
|
||||
cor: "red",
|
||||
descricao: "Null pointers, memory access violations (Load/StoreProhibited), illegal instructions, and cache panics in ISRs.",
|
||||
},
|
||||
{
|
||||
id: "freertos",
|
||||
nome: "FreeRTOS & Multitasking",
|
||||
icone: "Layers",
|
||||
cor: "purple",
|
||||
descricao: "Task Watchdog (TWDT), Interrupt Watchdog (IWDT), Stack Overflow, and scheduler deadlocks.",
|
||||
},
|
||||
{
|
||||
id: "memoria",
|
||||
nome: "Memory, Heap & PSRAM",
|
||||
icone: "Activity",
|
||||
cor: "blue",
|
||||
descricao: "Heap fragmentation, Memory Leaks, DMA allocations, and PSRAM limitations.",
|
||||
},
|
||||
{
|
||||
id: "boot-flash",
|
||||
nome: "Bootloader & Flashing",
|
||||
icone: "Terminal",
|
||||
cor: "emerald",
|
||||
descricao: "Serial communication failures (DTR/RTS), SPI Flash read errors, clock mismatch, and invalid partitions.",
|
||||
},
|
||||
{
|
||||
id: "conectividade",
|
||||
nome: "Connectivity & Protocols",
|
||||
icone: "Wifi",
|
||||
cor: "cyan",
|
||||
descricao: "Wi-Fi Beacon Timeout, TLS/HTTPS handshake failures due to lack of SNTP clock, and signal instability.",
|
||||
},
|
||||
];
|
||||
|
||||
export const sintomasRapidos = [
|
||||
{ id: "bootloop", rotulo: "🔄 Bootloop (Crash loop)", categoria: "todos" },
|
||||
{ id: "wifi-crash", rotulo: "📶 Crashes when enabling Wi-Fi/BLE", categoria: "alimentacao" },
|
||||
{ id: "upload-fail", rotulo: "🔌 Upload failed (Flashing error)", categoria: "boot-flash" },
|
||||
{ id: "random-freeze", rotulo: "⏱️ Freezes after minutes/hours", categoria: "memoria" },
|
||||
{ id: "null-pointer", rotulo: "💥 Guru Meditation (Crash)", categoria: "cpu-panics" },
|
||||
{ id: "wdt-reset", rotulo: "🐕 Watchdog Triggered", categoria: "freertos" },
|
||||
{ id: "tls-fail", rotulo: "🔒 HTTPS / SSL failure", categoria: "conectividade" },
|
||||
];
|
||||
|
||||
export const errosCatalogo = [
|
||||
{
|
||||
id: "brownout-reset",
|
||||
titulo: "Brownout Detector Reset (Voltage Drop)",
|
||||
categoria: "alimentacao",
|
||||
sintomas: ["bootloop", "wifi-crash"],
|
||||
gravidade: "High",
|
||||
logSerial: "Brownout detector was triggered\n\nrst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)",
|
||||
resumo: "ESP32 supply voltage dropped below the safe operating threshold (approximately 2.8V ~ 2.43V).",
|
||||
causaRaiz:
|
||||
"When Wi-Fi or BLE radios initialize, the power amplifier (PA) draws instantaneous current spikes exceeding 500 mA within less than 1 ms. If the power supply, long/thin USB cables, breadboard rails, or LDO regulator cannot supply transient current with low impedance, the voltage on the 3V3 rail collapses momentarily, triggering the internal Brownout comparator circuit to prevent Flash corruption and undefined logic states.",
|
||||
gambiarra: {
|
||||
titulo: "Disabling Brownout detector in software",
|
||||
descricao: "Calling WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0) to suppress the error in code.",
|
||||
consequencia: "Extremely dangerous: the ESP32 continues executing instructions under undervoltage, corrupting SPI Flash memory, locking peripheral registers, and causing erratic field failures without notice.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Proper hardware sizing and decoupling capacitors",
|
||||
passos: [
|
||||
"Add a 10 µF to 100 µF low-ESR tantalum or ceramic capacitor in parallel with a 100 nF ceramic capacitor as close as possible to the 3V3 and GND pins of the ESP32.",
|
||||
"Use LDO regulators rated for at least 600 mA to 1 A peaks with excellent transient response (e.g. AP2112K, ME6211, TPS73733, or robust XC6206). Avoid low-grade AMS1117 clones.",
|
||||
"Avoid powering the ESP32 through long breadboard power rails with thin jumper wires when Wi-Fi transmits at full power.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// Do NOT disable the Brownout detector! If you need to reduce current peaks in bench testing:
|
||||
#include <WiFi.h>
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
// Optional: Slightly reducing maximum Wi-Fi TX power from 20dBm to 17dBm cuts current spikes by ~20%
|
||||
WiFi.setTxPower(WIFI_POWER_17dBm);
|
||||
WiFi.begin("SSID", "PASSWORD");
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF configuration:
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
void app_main(void) {
|
||||
// In menuconfig: Component config -> ESP32-specific -> Hardware Brownout Reset (Keep ENABLED)
|
||||
// To mitigate transient peaks in power-constrained designs:
|
||||
esp_wifi_set_max_tx_power(68); // 68 = 17dBm (units of 0.25dBm)
|
||||
}`,
|
||||
codigoMicroPython: `# Safe Wi-Fi connection in MicroPython with supply stabilization:
|
||||
import network
|
||||
import time
|
||||
|
||||
wlan = network.WLAN(network.STA_IF)
|
||||
wlan.active(True)
|
||||
|
||||
# Wait for supply rails to settle before turning on transmitter
|
||||
time.sleep_ms(200)
|
||||
wlan.connect("SSID", "PASSWORD")
|
||||
|
||||
attempts = 0
|
||||
while not wlan.isconnected() and attempts < 30:
|
||||
time.sleep_ms(200)
|
||||
attempts += 1
|
||||
|
||||
if wlan.isconnected():
|
||||
print("Wi-Fi Connected! IP:", wlan.ifconfig()[0])
|
||||
else:
|
||||
print("[ERROR] Failed to connect Wi-Fi")`,
|
||||
dicaPro: "If designing custom PCBs, route a solid ground plane directly beneath the module and keep 3.3V power traces at 0.5 mm to 1 mm minimum width to prevent resistive voltage drop (IR drop) during RF bursts.",
|
||||
},
|
||||
{
|
||||
id: "strapping-pins",
|
||||
titulo: "Strapping Pin Conflict at Boot",
|
||||
categoria: "alimentacao",
|
||||
sintomas: ["bootloop", "upload-fail"],
|
||||
gravidade: "Critical",
|
||||
logSerial: "rst:0x1 (POWERON_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)\nflash read err, 1000\nwaiting for download",
|
||||
resumo: "The ESP32 fails to boot firmware from Flash or enters download mode unintentionally because a strapping pin was pulled to an incorrect logic level during reset.",
|
||||
causaRaiz:
|
||||
"The instant EN/CHIP_PU rises (Power-On Reset), the CPU latches the electrical logic level on specific strapping pins to configure Flash voltage (1.8V vs 3.3V), boot mode (UART Download vs SPI Flash Boot), and clock output. Connecting external sensors, relays, or LEDs with pull-up/pull-down resistors to these pins forces invalid strapping states, halting the bootloader.",
|
||||
gambiarra: {
|
||||
titulo: "Adding delays in code or manually disconnecting cables at each boot",
|
||||
descricao: "Attempting to fix the problem in setup() or manually unplugging wires before every reset.",
|
||||
consequencia: "Useless: Strapping pins are sampled by silicon hardware before the CPU executes a single line of application code or the second-stage bootloader.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Safe GPIO allocation and reset isolation",
|
||||
passos: [
|
||||
"ESP32 (Classic): Avoid using GPIO 0 (Boot mode), GPIO 2 (must be LOW or floating during flashing), GPIO 12 (selects Flash voltage: pulling HIGH at reset burns/locks 3.3V flash), and GPIO 15 (suppresses boot log output if LOW).",
|
||||
"ESP32-C3: Avoid pulling GPIO 8 LOW or GPIO 9 LOW during reset.",
|
||||
"ESP32-S3: Watch GPIO 0, GPIO 45 (VDD_SPI voltage level), and GPIO 46.",
|
||||
"If these pins must interface with peripherals, use transistors or digital bus switches to isolate them until the EN pin has completely risen and stabilized.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// SAFE PINOUT RECOMMENDATIONS (ESP32 Classic):
|
||||
// Preferred pins for I2C / SPI / General Sensors:
|
||||
// SDA: GPIO 21 | SCL: GPIO 22
|
||||
// SPI: MOSI 23 | MISO 19 | SCK 18 | CS 5
|
||||
|
||||
// WARNING: GPIOs 34, 35, 36 (VP), 39 (VN) are INPUT-ONLY (no internal pull-up/pull-down).
|
||||
// Never configure them as pinMode(..., OUTPUT); nor for I2C/SPI buses.`,
|
||||
codigoEspIdf: `// In ESP-IDF, lock Flash voltage via eFuse to free GPIO 12 (WARNING: IRREVERSIBLE):
|
||||
// If using classic ESP32 and GPIO 12 is needed for peripherals:
|
||||
// espefuse.py --port /dev/ttyUSB0 set_flash_voltage 3.3V
|
||||
// This permanently disables hardware strapping sampling on GPIO 12.`,
|
||||
codigoMicroPython: `# Safe pin setup in MicroPython:
|
||||
from machine import Pin
|
||||
|
||||
# Safe pins for outputs and buttons with internal pull-up:
|
||||
led = Pin(2, Pin.OUT) # GPIO 2
|
||||
button = Pin(4, Pin.IN, Pin.PULL_UP) # GPIO 4 (safe)
|
||||
|
||||
# Pins 34, 35, 36, 39 are INPUT-ONLY with no internal pull-ups:
|
||||
analog_sensor = Pin(36, Pin.IN) # Correct (requires external pull-up if used as a digital input)`,
|
||||
dicaPro: "Remember: Input-only pins (GPI 34 to 39 on classic ESP32) have neither internal silicon pull-up/pull-down circuits nor output drivers. External resistors are mandatory.",
|
||||
},
|
||||
{
|
||||
id: "guru-load-prohibited",
|
||||
titulo: "Guru Meditation: LoadProhibited / StoreProhibited",
|
||||
categoria: "cpu-panics",
|
||||
sintomas: ["bootloop", "null-pointer"],
|
||||
gravidade: "Critical",
|
||||
logSerial: "Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.\nCore 0 register dump:\nPC : 0x400d14bc PS : 0x00060830 A0 : 0x800d1512 A1 : 0x3ffb1f20 \nEXCVADDR: 0x00000000",
|
||||
resumo: "The CPU attempted to read (Load) or write (Store) to an inaccessible or invalid memory address, typically null pointer 0x00000000.",
|
||||
causaRaiz:
|
||||
"This is the classic null pointer dereference or dangling pointer access. The EXCVADDR register shows the faulty memory address: if EXCVADDR is 0x00000000 or near zero (e.g. 0x00000008, a struct offset), code attempted to access members of an uninitialized object or a failed malloc allocation.",
|
||||
gambiarra: {
|
||||
titulo: "Inserting random delays or rebooting in loop without fixing root cause",
|
||||
descricao: "Assuming it is a timing glitch and scattering delay() calls or masking reboots.",
|
||||
consequencia: "The firmware continues crashing intermittently in production whenever the null pointer condition recurs.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Defensive validation and Backtrace decoding",
|
||||
passos: [
|
||||
"Always verify that pointers returned by allocation or lookup functions (malloc, WiFi.client(), JSON parsing, xQueueReceive) are non-NULL before accessing their fields.",
|
||||
"Install 'Espressif Exception Decoder' in your IDE (Arduino IDE / PlatformIO) or run 'xtensa-esp32-elf-addr2line -pfia -e firmware.elf 0x400d14bc' to pinpoint the exact line of code that triggered the crash.",
|
||||
"In ESP-IDF, run 'idf.py monitor' which decodes the call backtrace in real-time.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// DEFENSIVE CODING:
|
||||
struct SensorData {
|
||||
float temperature;
|
||||
float humidity;
|
||||
};
|
||||
|
||||
void processSensor(SensorData* sensor) {
|
||||
// Mandatory check against LoadProhibited:
|
||||
if (sensor == nullptr) {
|
||||
Serial.println("[ERROR] Null sensor pointer!");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.printf("Temp: %.1f C\\n", sensor->temperature);
|
||||
}`,
|
||||
codigoEspIdf: `// In ESP-IDF, use ESP_RETURN_ON_FALSE or explicit assertions:
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
|
||||
static const char* TAG = "SENSOR";
|
||||
|
||||
esp_err_t read_data(char* buffer, size_t max_len) {
|
||||
ESP_RETURN_ON_FALSE(buffer != NULL, ESP_ERR_INVALID_ARG, TAG, "Null buffer supplied!");
|
||||
// Safe operation...
|
||||
return ESP_OK;
|
||||
}`,
|
||||
codigoMicroPython: `# Preventing NoneType exceptions in MicroPython:
|
||||
import json
|
||||
|
||||
def process_sensor(raw_data):
|
||||
if raw_data is None:
|
||||
print("[ERROR] Null data received!")
|
||||
return None
|
||||
|
||||
try:
|
||||
obj = json.loads(raw_data)
|
||||
# Safe lookup with fallback default
|
||||
temperature = obj.get("temp", 0.0)
|
||||
return temperature
|
||||
except (ValueError, AttributeError) as e:
|
||||
print("Error processing payload:", e)
|
||||
return None`,
|
||||
dicaPro: "If EXCVADDR is 0x3fxxxxxx or 0x40xxxxxx but the code crashes, you likely experienced a buffer overflow that corrupted adjacent pointers in RAM.",
|
||||
},
|
||||
{
|
||||
id: "guru-iram-cache",
|
||||
titulo: "Cache Error / InstructionFetchError in ISRs",
|
||||
categoria: "cpu-panics",
|
||||
sintomas: ["bootloop", "null-pointer"],
|
||||
gravidade: "High",
|
||||
logSerial: "Guru Meditation Error: Core 0 panic'ed (Cache disabled but cached memory region accessed)\nGuru Meditation Error: Core 0 panic'ed (InstructionFetchError)",
|
||||
resumo: "An interrupt service routine (ISR) tried to execute code or read constants from SPI Flash while the Flash memory controller was disabled for a write or erase operation.",
|
||||
causaRaiz:
|
||||
"By default, ESP32 application code resides in external SPI Flash and is fetched into CPU execution pipeline via internal Instruction Cache. When the ESP32 writes to Flash (such as NVS commits, LittleFS, SPIFFS, or OTA updates), the hardware cache is momentarily disabled. If an ISR fires during this window and its function body resides in Flash, the CPU cannot fetch the instruction and enters an immediate panic.",
|
||||
gambiarra: {
|
||||
titulo: "Disabling all interrupts before writing to Flash",
|
||||
descricao: "Wrapping Flash file operations in indiscriminate noInterrupts() blocks.",
|
||||
consequencia: "Causes dropped sensor pulses, jitter on system timers, and potential watchdog resets.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Allocating ISRs and callback constants in IRAM / DRAM",
|
||||
passos: [
|
||||
"Decorate EVERY hardware interrupt handler with the IRAM_ATTR attribute (e.g., void IRAM_ATTR isrHandler()).",
|
||||
"Ensure any variables or constant strings accessed inside the ISR reside in DRAM (avoid inline string literals in ISR without DRAM_ATTR in ESP-IDF).",
|
||||
"Never call heavy library functions (such as Serial.print or floating-point formatting) inside an interrupt handler.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// ISR properly placed in internal IRAM:
|
||||
volatile uint32_t pulseCount = 0;
|
||||
|
||||
void IRAM_ATTR handleGpioInterrupt() {
|
||||
pulseCount++;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
pinMode(4, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(4), handleGpioInterrupt, FALLING);
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF:
|
||||
#include "esp_attr.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
static volatile uint32_t pulses = 0;
|
||||
|
||||
// Placed explicitly in IRAM:
|
||||
static void IRAM_ATTR gpio_isr_handler(void* arg) {
|
||||
pulses++;
|
||||
}
|
||||
|
||||
void app_main(void) {
|
||||
gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
|
||||
gpio_isr_handler_add(GPIO_NUM_4, gpio_isr_handler, NULL);
|
||||
}`,
|
||||
codigoMicroPython: `# Safe interrupt handling (ISR) in MicroPython:
|
||||
import micropython
|
||||
from machine import Pin
|
||||
|
||||
# Pre-allocate emergency exception buffer for ISR debugging:
|
||||
micropython.alloc_emergency_exception_buf(100)
|
||||
|
||||
pulse_count = 0
|
||||
|
||||
# Interrupt callback: do NOT allocate memory (no new strings, no new floats)
|
||||
def handle_pulse(pin):
|
||||
global pulse_count
|
||||
pulse_count += 1
|
||||
|
||||
sensor = Pin(4, Pin.IN, Pin.PULL_UP)
|
||||
sensor.irq(trigger=Pin.IRQ_FALLING, handler=handle_pulse)`,
|
||||
dicaPro: "When passing ESP_INTR_FLAG_IRAM in ESP-IDF, every function invoked by the ISR (including FreeRTOS API calls) MUST support IRAM (e.g. xQueueSendFromISR).",
|
||||
},
|
||||
{
|
||||
id: "freertos-twdt",
|
||||
titulo: "Task Watchdog Timer (TWDT) Timeout",
|
||||
categoria: "freertos",
|
||||
sintomas: ["bootloop", "wdt-reset"],
|
||||
gravidade: "Critical",
|
||||
logSerial: "E (10532) task_wdt: Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:\nE (10532) task_wdt: - IDLE0 (CPU 0)\nTask watchdog got triggered. System will be reset.",
|
||||
resumo: "A high-priority task entered a busy loop without yielding CPU time, preventing the FreeRTOS IDLE task from feeding the watchdog.",
|
||||
causaRaiz:
|
||||
"FreeRTOS runs an essential priority-0 task called IDLE on each CPU core. The Task Watchdog monitors whether the IDLE task executes periodically (by default, within 5 seconds). If a task with priority >= 1 runs a tight while(1) loop without blocking calls (vTaskDelay, queue reads, semaphores), it starves the IDLE task, triggering an emergency hardware reset.",
|
||||
gambiarra: {
|
||||
titulo: "Disabling Task Watchdog in menuconfig or increasing timeout to 60s",
|
||||
descricao: "Turning off the TWDT to prevent the board from rebooting.",
|
||||
consequencia: "If the firmware encounters an unexpected deadlock or infinite loop, the device freezes permanently and requires manual power cycling.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Event-driven architecture and periodic CPU yield",
|
||||
passos: [
|
||||
"Never write empty busy-wait loops like while(!condition); in FreeRTOS tasks.",
|
||||
"Always insert vTaskDelay(pdMS_TO_TICKS(10)) or wait for events with xQueueReceive(), ulTaskNotifyTake(), or xSemaphoreTake() with a timeout.",
|
||||
"If heavy compute tasks must run continuously, feed the watchdog explicitly via esp_task_wdt_reset().",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// CORRECT ARDUINO FREERTOS PATTERN:
|
||||
void myTask(void *pvParameters) {
|
||||
for (;;) {
|
||||
float sensorValue = analogRead(36);
|
||||
|
||||
// YIELD CPU to FreeRTOS scheduler and IDLE task:
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); // Non-blocking 100ms pause
|
||||
}
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF Task Watchdog pattern:
|
||||
#include "esp_task_wdt.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
void compute_task(void *pvParameters) {
|
||||
esp_task_wdt_add(NULL);
|
||||
|
||||
while (1) {
|
||||
// Compute...
|
||||
|
||||
// Feed watchdog during long processing cycles:
|
||||
esp_task_wdt_reset();
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
}
|
||||
}`,
|
||||
codigoMicroPython: `# Watchdog and non-blocking tasks with uasyncio in MicroPython:
|
||||
from machine import WDT
|
||||
import uasyncio as asyncio
|
||||
|
||||
wdt = WDT(timeout=5000)
|
||||
|
||||
async def sensor_task():
|
||||
while True:
|
||||
wdt.feed()
|
||||
await asyncio.sleep_ms(100)
|
||||
|
||||
async def main():
|
||||
asyncio.create_task(sensor_task())
|
||||
while True:
|
||||
await asyncio.sleep(1)
|
||||
|
||||
asyncio.run(main())`,
|
||||
dicaPro: "In Arduino, delay(ms) internally calls vTaskDelay. However, delayMicroseconds() or raw compute loops do not yield CPU time and will trigger the TWDT if held for more than a few seconds.",
|
||||
},
|
||||
{
|
||||
id: "freertos-stack-overflow",
|
||||
titulo: "Stack Overflow (Task Stack Depletion)",
|
||||
categoria: "freertos",
|
||||
sintomas: ["bootloop", "null-pointer"],
|
||||
gravidade: "Critical",
|
||||
logSerial: "Guru Meditation Error: Core 1 panic'ed (Unhandled debug exception).\nDebug exception reason: Stack canary watchpoint triggered (my_task)",
|
||||
resumo: "The task consumed more stack memory than allocated upon creation, corrupting the RTOS protection canary.",
|
||||
causaRaiz:
|
||||
"Each FreeRTOS task is allocated a fixed contiguous memory block for local variables, function arguments, and return addresses. Declaring large arrays on the stack (e.g., char buffer[2048];), heavy JSON documents, or deep call recursions within a default 2048-byte stack overflows the boundary and overwrites adjacent memory.",
|
||||
gambiarra: {
|
||||
titulo: "Assigning 64KB stack blindly to every task",
|
||||
descricao: "Inflating task stack sizes indiscriminately to avoid overflow crashes.",
|
||||
consequencia: "The ~320 KB usable SRAM of the ESP32 is quickly exhausted, leading to out-of-memory errors in Wi-Fi and TLS allocations.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Deliberate stack sizing and HighWaterMark monitoring",
|
||||
passos: [
|
||||
"Measure actual stack consumption using uxTaskGetStackHighWaterMark(). It returns the minimum free stack remaining since task creation.",
|
||||
"Move large buffers from the stack to the heap (using malloc/free) or declare them static outside function scope if reused.",
|
||||
"Tasks running secure TLS/HTTPS or MQTT over SSL connections require at least 6 KB to 8 KB of stack due to MbedTLS cryptographic frame complexity.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// MONITORING TASK STACK IN ARDUINO:
|
||||
void sensorTask(void *pvParameters) {
|
||||
for (;;) {
|
||||
// Task workload...
|
||||
|
||||
UBaseType_t freeStack = uxTaskGetStackHighWaterMark(NULL);
|
||||
Serial.printf("[STACK] Remaining free stack: %d bytes\\n", (int)freeStack);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
// Allocate 4096 bytes (4KB) with safety margin:
|
||||
xTaskCreatePinnedToCore(sensorTask, "sensorTask", 4096, NULL, 1, NULL, 1);
|
||||
}`,
|
||||
codigoEspIdf: `// Enable double stack checking in menuconfig:
|
||||
// Component config -> FreeRTOS -> Set a end of stack check -> Option 2 (Check by Stack Canary)
|
||||
// This catches overflows BEFORE memory structures become silently corrupted at runtime.`,
|
||||
codigoMicroPython: `# Memory and stack inspection in MicroPython:
|
||||
import gc
|
||||
import micropython
|
||||
|
||||
micropython.mem_info()
|
||||
|
||||
gc.collect()
|
||||
print("Free Heap:", gc.mem_free(), "bytes")
|
||||
print("Allocated Heap:", gc.mem_alloc(), "bytes")`,
|
||||
dicaPro: "If a function only processes an HTTP or JSON payload occasionally, allocate the buffer dynamically on the heap during the transaction and free it immediately, rather than permanently inflating task stack.",
|
||||
},
|
||||
{
|
||||
id: "memoria-fragmentacao-heap",
|
||||
titulo: "Heap Fragmentation and Memory Leaks",
|
||||
categoria: "memoria",
|
||||
sintomas: ["random-freeze", "tls-fail"],
|
||||
gravidade: "High",
|
||||
logSerial: "E (45892) mbedtls: mbedtls_ssl_setup returned -0x7f00\nE (45892) esp-tls: create_ssl_handle failed\nE (45893) HTTP_CLIENT: Connection failed, out of memory",
|
||||
resumo: "The ESP32 fails to allocate memory despite reporting a seemingly adequate total free heap size.",
|
||||
causaRaiz:
|
||||
"Heap memory becomes fragmented after thousands of allocations and deallocations of varying sizes over time (common when repeatedly concatenating Arduino String objects in loops). Free heap becomes split into tiny isolated chunks. When Wi-Fi or TLS libraries request a single contiguous 40 KB block for an SSL certificate buffer, malloc fails even if 100 KB total free memory exists across disconnected fragments.",
|
||||
gambiarra: {
|
||||
titulo: "Scheduling periodic ESP.restart() every few hours",
|
||||
descricao: "Triggering a daily reboot to reset fragmented memory.",
|
||||
consequencia: "Merely conceals the bug: during traffic spikes the device crashes well ahead of the scheduled reboot.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Eliminate dynamic strings and use pre-allocated static buffers",
|
||||
passos: [
|
||||
"In Arduino, avoid the String class. Use standard C-style character arrays (char buffer[128];) with safe snprintf().",
|
||||
"Monitor fragmentation by comparing total free memory (heap_caps_get_free_size) with the largest contiguous free block (heap_caps_get_largest_free_block).",
|
||||
"In complex ESP-IDF firmware, enable Heap Memory Tracing (CONFIG_HEAP_TRACING) to locate missing free() calls.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// COMPARISON:
|
||||
// ❌ AVOID (Causes severe heap fragmentation):
|
||||
// String json = "{\\"temp\\":";
|
||||
// json += String(temperature) + "}";
|
||||
|
||||
// ✅ RECOMMENDED (Zero heap allocations):
|
||||
char payload[64];
|
||||
snprintf(payload, sizeof(payload), "{\\"temp\\":%.2f,\\"hum\\":%.2f}", temperature, humidity);
|
||||
|
||||
// Health check:
|
||||
Serial.printf("Free Heap: %u | Largest Block: %u\\n",
|
||||
ESP.getFreeHeap(),
|
||||
ESP.getMaxAllocHeap());`,
|
||||
codigoEspIdf: `// Heap monitoring in ESP-IDF:
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
void inspect_memory(void) {
|
||||
size_t total_free = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
size_t largest_block = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
|
||||
|
||||
ESP_LOGI("HEAP", "Total free: %d bytes | Largest contiguous: %d bytes", total_free, largest_block);
|
||||
}`,
|
||||
codigoMicroPython: `# Preventing heap fragmentation in MicroPython:
|
||||
import gc
|
||||
|
||||
gc.enable()
|
||||
|
||||
# Pre-allocate reusable bytearrays instead of instantiating new strings:
|
||||
rx_buffer = bytearray(256)
|
||||
|
||||
def read_sensor_zero_alloc(stream):
|
||||
bytes_read = stream.readinto(rx_buffer)
|
||||
return rx_buffer[:bytes_read]
|
||||
|
||||
gc.collect()
|
||||
print(f"Free Heap: {gc.mem_free()} B | Allocated: {gc.mem_alloc()} B")`,
|
||||
dicaPro: "If the largest contiguous free block drops below 35 KB to 40 KB, modern HTTPS/TLS connections will fail during the cryptographic handshake.",
|
||||
},
|
||||
{
|
||||
id: "memoria-dma-psram",
|
||||
titulo: "DMA Allocation Failure in External Memory (PSRAM)",
|
||||
categoria: "memoria",
|
||||
sintomas: ["bootloop", "random-freeze"],
|
||||
gravidade: "High",
|
||||
logSerial: "E (1204) spi_master: spi_bus_initialize: DMA channel not compatible with external RAM buffer\nESP_ERROR_CHECK failed: esp_err_t 0x102 (ESP_ERR_INVALID_ARG)",
|
||||
resumo: "Firmware attempted to pass a buffer allocated in external PSRAM to a DMA-driven peripheral (SPI, I2S, LCD, SDMMC) that can only access internal SRAM.",
|
||||
causaRaiz:
|
||||
"On ESP32 family chips (especially classic ESP32, ESP32-S2, and ESP32-S3 standard bus), the peripheral DMA engine has no direct physical access to external SPI/QSPI PSRAM. DMA transfers strictly require source and destination buffers to reside in internal SRAM.",
|
||||
gambiarra: {
|
||||
titulo: "Disabling DMA on peripherals",
|
||||
descricao: "Switching SPI/I2S buses to polled CPU transfer mode without DMA.",
|
||||
consequencia: "Throughput plummets and the CPU core stays 100% occupied during display updates or audio streaming.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Explicit allocation with MALLOC_CAP_DMA and MALLOC_CAP_INTERNAL",
|
||||
passos: [
|
||||
"Always allocate DMA buffers using heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL).",
|
||||
"Keep heavy non-DMA assets (decoded images, machine learning weights, inactive audio) in PSRAM, copying small frames to internal DMA buffers on demand (ping-pong buffering).",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// Allocating DMA buffers in Arduino ESP32:
|
||||
#include <esp_heap_caps.h>
|
||||
|
||||
uint8_t* dmaBuffer = nullptr;
|
||||
|
||||
void setup() {
|
||||
size_t size = 4096;
|
||||
// Guarantees buffer is allocated in DMA-accessible internal SRAM:
|
||||
dmaBuffer = (uint8_t*) heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
|
||||
if (dmaBuffer == nullptr) {
|
||||
Serial.println("[ERROR] Failed to allocate internal DMA buffer!");
|
||||
}
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF:
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
uint8_t* allocate_spi_buffer(size_t len) {
|
||||
return (uint8_t*) heap_caps_aligned_alloc(4, len, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
}`,
|
||||
codigoMicroPython: `# In MicroPython, inspect available PSRAM:
|
||||
import gc
|
||||
import esp32
|
||||
|
||||
print("Total accessible memory in MicroPython:", gc.mem_free() + gc.mem_alloc(), "bytes")
|
||||
buffer_spi = bytearray(1024)`,
|
||||
dicaPro: "On the ESP32-P4, the advanced AXI bus matrix enables DMA into specific external memory regions, but for the ESP32/S2/S3/C3 lines, internal SRAM placement is mandatory.",
|
||||
},
|
||||
{
|
||||
id: "boot-failed-connect",
|
||||
titulo: "Failed to connect to ESP32: Timed out waiting for packet header",
|
||||
categoria: "boot-flash",
|
||||
sintomas: ["upload-fail"],
|
||||
gravidade: "Medium",
|
||||
logSerial: "A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header\nesptool.py v4.6\nConnecting...................",
|
||||
resumo: "The programming tool (esptool / Arduino IDE / PlatformIO) was unable to place the microcontroller into UART bootloader mode.",
|
||||
causaRaiz:
|
||||
"To initiate flashing, the USB-UART bridge (CH340, CP2102, FTDI) toggles DTR and RTS lines to pull GPIO 0 LOW while pulsing EN/RST LOW then HIGH. On many third-party development boards, the RC timing circuit on EN lacks adequate capacitance to hold the reset state during the DTR transition.",
|
||||
gambiarra: {
|
||||
titulo: "Holding the physical BOOT button with your finger at every upload",
|
||||
descricao: "Pressing BOOT/GPIO 0 manually each time the compiler finishes generating binaries.",
|
||||
consequencia: "Inconvenient during rapid prototyping and impossible on sealed boards enclosed in enclosures.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Add a 10 µF capacitor on EN or verify USB data cable",
|
||||
passos: [
|
||||
"Solder a 10 µF (or 1 µF to 10 µF) ceramic or electrolytic capacitor between the EN (RST) and GND pins. This stabilizes the automatic reset ramp.",
|
||||
"Ensure the USB cable has active data lines (D+ and D-). Many cheap charging cables contain only power wires.",
|
||||
"On Linux, confirm your user belongs to the 'dialout' group (sudo usermod -a -G dialout $USER) and that the 'brltty' service is not holding the serial port.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// Command-line verification with esptool:
|
||||
// python -m esptool --port /dev/ttyUSB0 chip_id
|
||||
// If it prints the MAC and chip model, physical communication is working.`,
|
||||
codigoEspIdf: `// In ESP-IDF:
|
||||
// idf.py -p /dev/ttyUSB0 -b 460800 flash
|
||||
// If flashing fails at high speeds, reduce baud rate:
|
||||
// idf.py -p /dev/ttyUSB0 -b 115200 flash`,
|
||||
codigoMicroPython: `# Flashing official MicroPython firmware via terminal:
|
||||
# 1. Erase flash:
|
||||
# esptool.py --port /dev/ttyUSB0 erase_flash
|
||||
|
||||
# 2. Flash binary at safe baud rate:
|
||||
# esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 ESP32_GENERIC-*.bin`,
|
||||
dicaPro: "When using ESP32-S3 or C3 modules with native USB (Direct USB-JTAG), verify that your tooling is configured for the USB CDC/JTAG port rather than a legacy UART bridge.",
|
||||
},
|
||||
{
|
||||
id: "tls-sntp-clock-fail",
|
||||
titulo: "TLS/HTTPS Handshake Failure due to Desynchronized Clock",
|
||||
categoria: "conectividade",
|
||||
sintomas: ["tls-fail", "random-freeze"],
|
||||
gravidade: "High",
|
||||
logSerial: "E (15420) esp-tls-mbedtls: mbedtls_ssl_handshake returned -0x2700\nE (15420) esp-tls: Failed to verify peer certificate!\nE (15421) esp-tls: Verification info: The certificate is not yet valid (or has expired)",
|
||||
resumo: "Secure HTTPS, AWS IoT, MQTT over TLS, or Web API requests fail because the internal ESP32 RTC defaults to 01/01/1970.",
|
||||
causaRaiz:
|
||||
"Digital certificates (X.509 SSL/TLS) include strict validity windows (Not Before and Not After). Because typical ESP32 boards lack an external RTC battery, the internal clock resets to the Unix epoch (1970) on every cold boot. When MbedTLS checks the server certificate date, it deems it 'not yet valid' (since current dates are decades ahead of 1970), aborting the handshake with error -0x2700 (MBEDTLS_ERR_X509_CERT_VERIFY_FAILED).",
|
||||
gambiarra: {
|
||||
titulo: "Disabling SSL certificate verification (Insecure / No-Verify)",
|
||||
descricao: "Using client.setInsecure() in Arduino or turning off CA validation in ESP-IDF.",
|
||||
consequencia: "Creates a critical security vulnerability: the device is completely exposed to Man-in-the-Middle (MitM) attacks, allowing credentials and firmware to be intercepted.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Mandatory SNTP time synchronization prior to opening TLS sockets",
|
||||
passos: [
|
||||
"Immediately after acquiring an IP address, start the SNTP client querying reliable NTP servers (e.g. pool.ntp.org, time.google.com).",
|
||||
"Block outbound HTTPS/MQTT connections until system time is confirmed synchronized.",
|
||||
"Set the correct timezone string so log timestamps match local operational time.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// SNTP SYNCHRONIZATION BEFORE HTTPS IN ARDUINO:
|
||||
#include <WiFi.h>
|
||||
#include <time.h>
|
||||
|
||||
void syncClock() {
|
||||
configTime(0, 0, "pool.ntp.org", "time.google.com");
|
||||
|
||||
Serial.print("Waiting for NTP time sync");
|
||||
time_t now = time(nullptr);
|
||||
// Year 2024 in Unix timestamp is > 1700000000. If smaller, clock is still in 1970:
|
||||
while (now < 1700000000) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
now = time(nullptr);
|
||||
}
|
||||
Serial.println("\\n[OK] Clock synchronized! TLS handshakes enabled.");
|
||||
}`,
|
||||
codigoEspIdf: `// SNTP in ESP-IDF:
|
||||
#include "esp_sntp.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
void initialize_sntp(void) {
|
||||
ESP_LOGI("SNTP", "Starting SNTP client...");
|
||||
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||||
esp_sntp_setservername(0, "pool.ntp.org");
|
||||
esp_sntp_init();
|
||||
}`,
|
||||
codigoMicroPython: `# SNTP synchronization and HTTPS requests in MicroPython:
|
||||
import ntptime
|
||||
import time
|
||||
import urequests
|
||||
|
||||
def sync_and_request():
|
||||
try:
|
||||
print("Synchronizing clock via NTP...")
|
||||
ntptime.host = "pool.ntp.org"
|
||||
ntptime.settime()
|
||||
print("UTC Time synchronized:", time.localtime())
|
||||
|
||||
response = urequests.get("https://api.github.com")
|
||||
print("HTTPS Response:", response.status_code)
|
||||
response.close()
|
||||
except Exception as e:
|
||||
print("[TLS/NTP ERROR]:", e)`,
|
||||
dicaPro: "If operating in isolated local networks without internet access, configure a local NTP server on the gateway router or add a physical DS3231 RTC module over I2C.",
|
||||
},
|
||||
];
|
||||
|
||||
export const regrasDecodificadorLog = [
|
||||
{
|
||||
padrao: /Brownout detector was triggered/i,
|
||||
titulo: "Brownout Detector (Critical Undervoltage)",
|
||||
tipo: "Power / Hardware",
|
||||
explicacao:
|
||||
"Voltage on the 3.3V rail dropped below safe limits (typically caused by Wi-Fi/BLE RF transmit spikes or an underpowered power supply).",
|
||||
acaoRecomendada:
|
||||
"Add a 10 µF to 100 µF low-ESR capacitor on the VCC rail, verify power cables, and ensure the LDO regulator delivers adequate current.",
|
||||
},
|
||||
{
|
||||
padrao: /LoadProhibited|StoreProhibited/i,
|
||||
titulo: "Guru Meditation: Load/StoreProhibited (Null or Invalid Pointer)",
|
||||
tipo: "CPU Panic / Exception",
|
||||
explicacao:
|
||||
"Attempted to read or write to an invalid memory location (usually null pointer dereference or array index out of bounds).",
|
||||
acaoRecomendada:
|
||||
"Decode the Backtrace using Exception Decoder or 'addr2line' to find the exact line. Add defensive 'if (ptr != NULL)' validation.",
|
||||
},
|
||||
{
|
||||
padrao: /Cache disabled but cached memory region accessed|InstructionFetchError/i,
|
||||
titulo: "Interrupt Cache Error (ISR outside IRAM)",
|
||||
tipo: "CPU Panic / Flash",
|
||||
explicacao:
|
||||
"An interrupt handler (ISR) attempted to execute code from external Flash while Flash was busy with a write or erase operation (NVS, LittleFS, OTA).",
|
||||
acaoRecomendada:
|
||||
"Add the IRAM_ATTR attribute to the interrupt callback and ensure variables accessed inside the ISR reside in DRAM.",
|
||||
},
|
||||
{
|
||||
padrao: /Task watchdog got triggered/i,
|
||||
titulo: "Task Watchdog Timer (TWDT) Timeout",
|
||||
tipo: "FreeRTOS / Multitasking",
|
||||
explicacao:
|
||||
"A high-priority task monopolized the CPU without yielding (missing vTaskDelay or blocking queues), starving the FreeRTOS IDLE task.",
|
||||
acaoRecomendada:
|
||||
"Add vTaskDelay(pdMS_TO_TICKS(10)) inside compute loops, or use queues and semaphores instead of continuous while(1) loops.",
|
||||
},
|
||||
{
|
||||
padrao: /Stack canary watchpoint triggered/i,
|
||||
titulo: "Stack Overflow (Task Stack Exhaustion)",
|
||||
tipo: "FreeRTOS / Memory",
|
||||
explicacao:
|
||||
"The task exceeded the stack memory allocated during creation, corrupting the RTOS stack canary sentinel.",
|
||||
acaoRecomendada:
|
||||
"Increase task stack size in xTaskCreate (e.g. from 2048 to 4096 bytes) and allocate large arrays on the heap.",
|
||||
},
|
||||
{
|
||||
padrao: /Timed out waiting for packet header|Failed to connect to ESP32/i,
|
||||
titulo: "UART Connection / Upload Failure",
|
||||
tipo: "Bootloader / Connection",
|
||||
explicacao:
|
||||
"The host computer failed to place the ESP32 into flashing mode via DTR/RTS, or the USB cable lacks data lines.",
|
||||
acaoRecomendada:
|
||||
"Add a 10 µF capacitor between EN and GND, verify data cable continuity, or hold the physical BOOT button during upload initiation.",
|
||||
},
|
||||
{
|
||||
padrao: /The certificate is not yet valid|-0x2700/i,
|
||||
titulo: "SSL/TLS Certificate Failure (Clock stuck in 1970)",
|
||||
tipo: "Connectivity / TLS",
|
||||
explicacao:
|
||||
"The ESP32 attempted to validate an HTTPS/TLS server certificate with its internal clock unset at the Unix epoch (1970).",
|
||||
acaoRecomendada:
|
||||
"Synchronize time via SNTP (configTime in Arduino or ntptime.settime() in MicroPython) before making secure TLS requests.",
|
||||
},
|
||||
{
|
||||
padrao: /rst:0x1 \(POWERON_RESET\),boot:0x[0-9a-fA-F]+/i,
|
||||
titulo: "Power-On Reset / Strapping Pins Latch",
|
||||
tipo: "Hardware / Boot",
|
||||
explicacao:
|
||||
"The microcontroller rebooted and logged its strapping register. If it freezes immediately after, a strapping pin is held at an incorrect level.",
|
||||
acaoRecomendada:
|
||||
"Check that strapping GPIOs (0, 2, 12, 15 on ESP32 or 8, 9 on C3) are not pulled to incompatible states by external circuits at reset.",
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* Structured Technical Glossary Database for ESP32.
|
||||
* Covers all Espressif SoC series (ESP32, S2, S3, S31, C2, C3, C5, C6, C61, H2, H4, P4)
|
||||
* and their hardware, peripherals, radio, security and software features.
|
||||
*/
|
||||
|
||||
export const categoriasGlossario = [
|
||||
{
|
||||
id: "processamento",
|
||||
nome: "Processing, CPU & Silicon",
|
||||
icone: "Cpu",
|
||||
emoji: "🧠",
|
||||
cor: "blue",
|
||||
descricao: "Xtensa and RISC-V architectures, cores, ULP coprocessors, AI vector accelerators and floating-point units.",
|
||||
termos: [
|
||||
{
|
||||
termo: "Xtensa vs RISC-V Architecture",
|
||||
definicao: "Processor instruction set architecture. Classic ESP32, S2 and S3 use proprietary Tensilica Xtensa cores (LX6/LX7). Modern series C (C2, C3, C5, C6, C61), H (H2, H4) and P (P4) adopt the open, modular and energy-efficient 32-bit RISC-V architecture.",
|
||||
exemplo: "ESP32-S3 uses dual-core Xtensa LX7, while ESP32-C6 uses single-core RISC-V and ESP32-P4 features dual-core RISC-V at 400 MHz.",
|
||||
},
|
||||
{
|
||||
termo: "CPU Cores (Dual-Core vs Single-Core)",
|
||||
definicao: "Independent central processing units. Dual-core chips allow dedicating one core (Core 0) to Wi-Fi/Bluetooth protocol stacks and FreeRTOS scheduling, leaving the second core (Core 1) entirely free for user application tasks.",
|
||||
exemplo: "ESP32, ESP32-S3 and ESP32-P4 are dual-core; ESP32-S2, C2, C3, C6 and H2 are single-core.",
|
||||
},
|
||||
{
|
||||
termo: "ULP Coprocessor (Ultra Low Power)",
|
||||
definicao: "An ultra-low-power auxiliary processor that operates while the main CPU cores are asleep in Deep Sleep mode. It can monitor analog sensors, read GPIOs or scan I2C/SPI buses consuming microamps.",
|
||||
exemplo: "ESP32 includes an FSM/assembly ULP; ESP32-S2, S3, C5 and C6 integrate a 32-bit RISC-V ULP coprocessor running up to 20–48 MHz.",
|
||||
},
|
||||
{
|
||||
termo: "Vector Instructions & AI Acceleration",
|
||||
definicao: "SIMD (Single Instruction, Multiple Data) CPU extension designed for parallel mathematical operations, accelerating matrix multiplications, FFTs, audio filtering and neural network inference.",
|
||||
exemplo: "ESP32-S3 includes 128-bit vector extensions; ESP32-P4 features high-throughput vector instructions for DSP and machine vision.",
|
||||
},
|
||||
{
|
||||
termo: "FPU (Floating-Point Unit)",
|
||||
definicao: "Dedicated hardware module for single-precision IEEE 754 floating-point operations. Avoids software floating-point emulation, executing float math in single clock cycles.",
|
||||
exemplo: "ESP32, ESP32-S3 and ESP32-P4 have hardware FPU; ESP32-C3 uses software floating-point emulation.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "conectividade",
|
||||
nome: "Connectivity & Radio",
|
||||
icone: "Wifi",
|
||||
emoji: "📡",
|
||||
cor: "teal",
|
||||
descricao: "Wi-Fi 4, Wi-Fi 6, Bluetooth Dual Mode, BLE, Zigbee, Thread, Matter and wireless mesh networks.",
|
||||
termos: [
|
||||
{
|
||||
termo: "Wi-Fi 6 (802.11ax)",
|
||||
definicao: "Next-generation Wi-Fi standard delivering higher spectral efficiency, lower latency, and reduced power consumption via OFDMA and Target Wake Time (TWT).",
|
||||
exemplo: "ESP32-C6 and C5 support 802.11ax in 2.4 GHz; ESP32-C5 adds dual-band 5 GHz support.",
|
||||
},
|
||||
{
|
||||
termo: "Target Wake Time (TWT)",
|
||||
definicao: "A Wi-Fi 6 power-saving mechanism allowing the access point and ESP32 to negotiate scheduled sleep periods. The device stays asleep for hours and wakes only at negotiated transmission times.",
|
||||
exemplo: "Battery-powered ESP32-C6 sensors use TWT to preserve battery life while remaining associated to Wi-Fi 6 routers.",
|
||||
},
|
||||
{
|
||||
termo: "Bluetooth LE Audio & Isochronous Channels",
|
||||
definicao: "Next-generation Bluetooth audio architecture using the LC3 codec over isochronous BIS/CIS channels, enabling broadcast audio (Auracast) and ultra-low latency.",
|
||||
exemplo: "ESP32-H4 supports Bluetooth 5.4 LE Audio with isochronous streams.",
|
||||
},
|
||||
{
|
||||
termo: "Thread & IEEE 802.15.4",
|
||||
definicao: "An open, IPv6-based, low-power wireless mesh networking protocol designed specifically for smart home automation.",
|
||||
exemplo: "ESP32-H2 and ESP32-C6 feature an IEEE 802.15.4 radio supporting Thread and Zigbee.",
|
||||
},
|
||||
{
|
||||
termo: "Matter Protocol",
|
||||
definicao: "A unified application layer protocol running over IPv6 (Wi-Fi, Thread and Ethernet) ensuring seamless cross-ecosystem interoperability across Apple Home, Google Home, Alexa and SmartThings.",
|
||||
exemplo: "ESP32-C6, H2 and S3 devices run ESP-Matter firmware certified for cross-platform smart home setups.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "memoria",
|
||||
nome: "Memory & Buses",
|
||||
icone: "Database",
|
||||
emoji: "💾",
|
||||
cor: "purple",
|
||||
descricao: "Internal SRAM, RTC fast/slow memory, external Flash, PSRAM, cache architecture and memory-mapped SPI buses.",
|
||||
termos: [
|
||||
{
|
||||
termo: "Internal SRAM & Memory Regions",
|
||||
definicao: "High-speed static RAM embedded on the silicon die. Divided into instruction SRAM (IRAM) and data SRAM (DRAM).",
|
||||
exemplo: "Classic ESP32 provides 520 KB of internal SRAM; ESP32-P4 includes 768 KB on-chip L2 SRAM.",
|
||||
},
|
||||
{
|
||||
termo: "PSRAM (Pseudo-Static RAM)",
|
||||
definicao: "External dynamic RAM with an internal self-refresh controller that communicates with the CPU via high-speed SPI/QSPI/OPI buses through cache memory.",
|
||||
exemplo: "ESP32-S3 modules commonly integrate 8 MB of Octal PSRAM for audio buffers and display framebuffers.",
|
||||
},
|
||||
{
|
||||
termo: "Flash Memory & Partition Table",
|
||||
definicao: "Non-volatile NOR flash memory storing bootloader, partition table, firmware application binaries and file systems (NVS, LittleFS, SPIFFS).",
|
||||
exemplo: "The partition table (partitions.csv) configures OTA slots (ota_0, ota_1) and storage partitions.",
|
||||
},
|
||||
{
|
||||
termo: "NVS (Non-Volatile Storage)",
|
||||
definicao: "A structured key-value storage library implemented inside dedicated flash partitions for persisting calibration parameters, Wi-Fi credentials and state.",
|
||||
exemplo: "Wi-Fi credentials and pairing keys are saved to NVS and retained across deep sleep cycles and reboots.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "perifericos",
|
||||
nome: "Peripherals & I/O",
|
||||
icone: "Sliders",
|
||||
emoji: "⚡",
|
||||
cor: "amber",
|
||||
descricao: "GPIO matrix, analog converters, serial communication buses, timers and specialized hardware interfaces.",
|
||||
termos: [
|
||||
{
|
||||
termo: "GPIO Matrix & Pin Muxing",
|
||||
definicao: "A flexible internal routing matrix that decouples internal peripheral signals (UART, SPI, I2C, PWM) from physical package pins, allowing almost any digital signal to route to any GPIO.",
|
||||
exemplo: "On the ESP32, hardware I2C or UART can be assigned to arbitrary digital GPIO pins in firmware.",
|
||||
},
|
||||
{
|
||||
termo: "Strapping Pins",
|
||||
definicao: "Dedicated physical pins sampled by hardware boot ROM during power-up or reset to determine boot mode (UART download vs SPI flash boot), VDD_SPI voltage and console logging.",
|
||||
exemplo: "GPIO0 pulled low during reset puts the ESP32 into ROM serial download mode for flashing.",
|
||||
},
|
||||
{
|
||||
termo: "SAR ADC & Non-Linearity",
|
||||
definicao: "Successive Approximation Register Analog-to-Digital Converter used for reading analog voltages. Requires software calibration for accurate readings near 0V and reference limits.",
|
||||
exemplo: "ESP-IDF esp_adc_cal APIs use factory calibration eFuses to convert raw ADC counts into calibrated millivolts.",
|
||||
},
|
||||
{
|
||||
termo: "TWAI / CAN Bus",
|
||||
definicao: "Two-Wire Automotive Interface, Espressif's implementation of the ISO 11898-1 CAN 2.0B / CAN FD standard for robust vehicle and industrial networking.",
|
||||
exemplo: "ESP32-S3 and P4 connect to CAN bus networks through external CAN transceivers (e.g. SN65HVD230).",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "seguranca",
|
||||
nome: "Hardware Security",
|
||||
icone: "ShieldCheck",
|
||||
emoji: "🔒",
|
||||
cor: "green",
|
||||
descricao: "Secure Boot, Flash Encryption, cryptographic hardware accelerators, eFuses and physical tamper resistance.",
|
||||
termos: [
|
||||
{
|
||||
termo: "eFuse (One-Time Programmable Memory)",
|
||||
definicao: "A block of one-time programmable microscopic electrical fuses on the silicon die storing MAC addresses, cryptographic keys, and permanent security configurations.",
|
||||
exemplo: "Secure Boot and Flash Encryption permanently lock configuration bits in eFuses during device manufacturing.",
|
||||
},
|
||||
{
|
||||
termo: "Secure Boot v2",
|
||||
definicao: "A cryptographic chain of trust starting in ROM code that verifies digital signatures (RSA-3072 or ECDSA) of bootloader and application binaries before execution.",
|
||||
exemplo: "Secure Boot prevents execution of unauthorized or tampered firmware on production ESP32 devices.",
|
||||
},
|
||||
{
|
||||
termo: "Flash Encryption",
|
||||
definicao: "On-the-fly transparent hardware encryption (AES-128 or XTS-AES-256) of external flash memory contents. The encryption key is stored securely in eFuses and never exposed.",
|
||||
exemplo: "Flash Encryption protects firmware intellectual property and sensitive credentials against physical flash readout.",
|
||||
},
|
||||
{
|
||||
termo: "Hardware Cryptographic Accelerators",
|
||||
definicao: "Dedicated silicon calculation blocks executing AES, SHA, RSA, ECC and RNG operations at hardware speeds without loading CPU cores.",
|
||||
exemplo: "Hardware AES and SHA accelerate TLS/HTTPS handshakes on ESP32 without stalling FreeRTOS tasks.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "energia",
|
||||
nome: "Power & Thermal Management",
|
||||
icone: "Battery",
|
||||
emoji: "🔋",
|
||||
cor: "emerald",
|
||||
descricao: "Deep Sleep, Light Sleep, brownout detection, power management algorithms and battery conservation.",
|
||||
termos: [
|
||||
{
|
||||
termo: "Deep Sleep Mode",
|
||||
definicao: "Ultra-low-power sleep state where high-performance CPU cores, digital peripherals, and radio are completely powered down, drawing only microamps.",
|
||||
exemplo: "In Deep Sleep, ESP32 consumes roughly 5–10 µA while RTC memory and timer remain active to wake the device.",
|
||||
},
|
||||
{
|
||||
termo: "Brownout Detector",
|
||||
definicao: "An internal hardware monitoring circuit that triggers a safe system reset if input VDD supply voltage drops below a calibrated threshold (~2.8V).",
|
||||
exemplo: "Sudden Wi-Fi transmit current spikes on weak power supplies trigger the Brownout detector to prevent memory corruption.",
|
||||
},
|
||||
{
|
||||
termo: "Wake-up Sources",
|
||||
definicao: "Configurable hardware triggers capable of waking the ESP32 from sleep modes, including RTC timers, external GPIO edges, touch pins and ULP signals.",
|
||||
exemplo: "esp_sleep_enable_ext0_wakeup configures a door sensor pin to instantly wake the chip from Deep Sleep.",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* Conhecimento de domínio da busca inteligente.
|
||||
*
|
||||
* Sem dependências nem alias de import: roda no servidor (montando o índice),
|
||||
* no navegador (interpretando a consulta) e em scripts de teste no Node.
|
||||
*
|
||||
* Todos os textos de `termos` já estão normalizados (minúsculos, sem acento).
|
||||
*/
|
||||
|
||||
export const normalizar = (s = "") =>
|
||||
String(s)
|
||||
.toLowerCase()
|
||||
.normalize("NFD")
|
||||
.replace(/[\u0300-\u036f]/g, "");
|
||||
|
||||
/**
|
||||
* Reconhece pinos ocupados por flash/PSRAM com base no que o diagrama diz.
|
||||
* "forte": o pino é consumido pela memória (ou é a alimentação dela).
|
||||
* "fraco": só é afetado em certos modos (ex.: SPI de 8 linhas/octal).
|
||||
* Avisos genéricos de tensão mínima ("para chips com flash integrada...") não contam.
|
||||
*/
|
||||
const nivelMemoria = (palavra) => (p) => {
|
||||
const citam = p._avs.filter((a) => a.includes(palavra) && !/^para chips (com|sem)/.test(a));
|
||||
if (citam.some((a) => /(utilizad|dedicad|conectad)/.test(a) && !/a menos que/.test(a))) return "forte";
|
||||
if (p._fn.some((f) => /alimentacao/.test(f) && f.includes(palavra))) return "forte";
|
||||
if (citam.length) return "fraco";
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Assuntos que o usuário pode citar. Cada um sabe:
|
||||
* - termos: como as pessoas escrevem (sinônimos, siglas, plurais comuns);
|
||||
* - pinoCats / pinoRe: como reconhecer os pinos relacionados no diagrama;
|
||||
* - pinoRotulo: frase usada no título do resultado de pinos.
|
||||
* Os dados de especificação ligam-se aos assuntos por SPEC_CAMPOS.
|
||||
*/
|
||||
export const TOPICOS = [
|
||||
{ id: "flash", nome: "Flash", termos: ["flash", "memoria flash", "spi flash", "armazenamento", "firmware", "rom externa"], pinoNivel: nivelMemoria("flash"), pinoRotulo: "connected to flash memory" },
|
||||
{ id: "psram", nome: "PSRAM", termos: ["psram", "ram externa", "spiram"], pinoNivel: nivelMemoria("psram"), pinoRotulo: "connected to PSRAM" },
|
||||
{ id: "memoria", nome: "Memory", termos: ["memoria", "sram", "heap", "rtc ram", "kb de ram", "memoria interna", "ram", "memory"], pinoRotulo: "" },
|
||||
{ id: "wifi", nome: "Wi-Fi", termos: ["wifi", "wi-fi", "wireless", "sem fio", "802.11", "wifi6", "wifi 6", "wi-fi 6"], pinoCats: ["Antena"], pinoRotulo: "antenna and radio pins" },
|
||||
{ id: "bluetooth", nome: "Bluetooth", termos: ["bluetooth", "ble", "bt", "bluetooth le", "mesh"], pinoCats: ["Antena"], pinoRotulo: "antenna and radio pins" },
|
||||
{ id: "zigbee", nome: "Zigbee/Thread", termos: ["zigbee", "thread", "802.15.4", "ieee 802.15.4"], pinoRotulo: "" },
|
||||
{ id: "matter", nome: "Matter", termos: ["matter", "casa inteligente", "smart home"], pinoRotulo: "" },
|
||||
{ id: "ethernet", nome: "Ethernet", termos: ["ethernet", "rmii", "cabo de rede", "lan"], pinoCats: ["Ethernet"], pinoRotulo: "Ethernet pins" },
|
||||
{ id: "can", nome: "CAN / TWAI", termos: ["can", "twai", "can bus", "canbus", "can fd"], pinoRe: /twai|\bcan\b/, pinoRotulo: "CAN/TWAI pins" },
|
||||
{ id: "usb", nome: "USB", termos: ["usb", "otg", "usb serial", "usb otg", "hid", "cdc"], pinoCats: ["USB"], pinoRotulo: "USB pins" },
|
||||
{ id: "jtag", nome: "JTAG / Debug", termos: ["jtag", "debug", "depuracao", "depurar", "openocd", "gdb"], pinoCats: ["JTAG"], pinoRotulo: "JTAG pins" },
|
||||
{ id: "adc", nome: "ADC", termos: ["adc", "analogico", "entrada analogica", "conversor analogico", "analogread", "saradc", "analog"], pinoCats: ["ADC"], pinoRotulo: "with ADC" },
|
||||
{ id: "dac", nome: "DAC", termos: ["dac", "saida analogica", "conversor digital"], pinoCats: ["DAC"], pinoRotulo: "with DAC" },
|
||||
{ id: "touch", nome: "Capacitive Touch", termos: ["touch", "capacitivo", "toque", "touchpad", "sensor de toque"], pinoCats: ["Touch"], pinoRotulo: "capacitive touch pins" },
|
||||
{ id: "uart", nome: "UART", termos: ["uart", "serial", "tx", "rx", "txd", "rxd", "porta serial"], pinoCats: ["UART"], pinoRotulo: "UART pins" },
|
||||
{ id: "spi", nome: "SPI", termos: ["spi", "mosi", "miso", "sclk", "barramento spi"], pinoCats: ["SPI"], pinoRotulo: "SPI pins" },
|
||||
{ id: "i2c", nome: "I2C", termos: ["i2c", "sda", "scl", "twi", "iic"], pinoCats: ["I2C"], pinoRotulo: "I2C pins" },
|
||||
{ id: "i2s", nome: "I2S", termos: ["i2s", "audio", "som", "microfone", "pdm", "codec"], pinoRe: /i2s|\bpdm\b/, pinoRotulo: "I2S / audio pins" },
|
||||
{ id: "pwm", nome: "PWM", termos: ["pwm", "ledc", "mcpwm", "servo", "dimmer"], pinoRe: /ledc|pwm/, pinoRotulo: "PWM pins" },
|
||||
{ id: "sd", nome: "SD Card / SDIO", termos: ["sd", "sdio", "sd card", "sdcard", "cartao sd", "microsd", "sdmmc", "mmc"], pinoCats: ["SD"], pinoRe: /sdio|sdmmc|\bsd\b/, pinoRotulo: "SD Card / SDIO pins" },
|
||||
{ id: "camera", nome: "Camera", termos: ["camera", "cam", "dvp", "csi", "mipi csi", "ov2640", "video"], pinoCats: ["CSI"], pinoRe: /\bcam\b|dvp|cam_/, pinoRotulo: "camera pins" },
|
||||
{ id: "lcd", nome: "Display / LCD", termos: ["lcd", "display", "tela", "dsi", "mipi dsi", "oled", "tft", "lvgl", "rgb"], pinoCats: ["DSI"], pinoRe: /lcd/, pinoRotulo: "display/LCD pins" },
|
||||
{ id: "strapping", nome: "Boot / Strapping", termos: ["strapping", "boot", "bootstrap", "modo de boot", "download mode", "modo de gravacao", "inicializacao"], pinoCats: ["Strapping"], pinoRotulo: "strapping (boot mode) pins" },
|
||||
{ id: "energia_pinos", nome: "Power", termos: ["alimentacao", "vdd", "3v3", "3.3v", "tensao", "regulador", "ldo", "fonte", "power"], pinoCats: ["Power"], pinoRotulo: "power pins" },
|
||||
{ id: "clock", nome: "Clock / Crystal", termos: ["clock", "xtal", "cristal", "oscilador", "32khz", "40mhz", "crystal"], pinoCats: ["Clock"], pinoRotulo: "clock/crystal pins" },
|
||||
{ id: "gpio", nome: "GPIO", termos: ["gpio", "entradas e saidas"], pinoCats: ["GPIO"], pinoRotulo: "GPIO pins" },
|
||||
{ id: "baixo_consumo", nome: "Low Power / ULP", termos: ["ulp", "lp core", "lp cpu", "coprocessador", "lp gpio", "low power", "rtc gpio"], pinoCats: ["Low Power"], pinoRotulo: "low-power (LP/RTC) pins" },
|
||||
{ id: "antena", nome: "Antenna / RF", termos: ["antena", "rf", "radiofrequencia", "ipex", "antenna"], pinoCats: ["Antena"], pinoRotulo: "antenna/RF pins" },
|
||||
{ id: "seguranca", nome: "Security", termos: ["seguranca", "secure boot", "criptografia", "encriptacao", "aes", "sha", "rsa", "hmac", "ecdsa", "efuse", "tee", "trng", "rng", "hsm", "protecao", "security"], pinoRotulo: "" },
|
||||
{ id: "consumo", nome: "Power Consumption", termos: ["consumo", "bateria", "deep sleep", "light sleep", "sleep", "modem sleep", "corrente", "miliamperes", "autonomia", "economia de energia", "low power mode", "power consumption"], pinoRotulo: "" },
|
||||
{ id: "temperatura", nome: "Temperature", termos: ["temperatura", "calor", "graus", "faixa de temperatura", "industrial", "temperature"], pinoRotulo: "" },
|
||||
{ id: "ia", nome: "AI / Acceleration", termos: ["ia", "ai", "machine learning", "ml", "tinyml", "vetorial", "inteligencia artificial", "rede neural", "esp-nn", "esp-dl"], pinoRotulo: "" },
|
||||
{ id: "processador", nome: "Processor", termos: ["processador", "cpu", "nucleo", "nucleos", "core", "dual core", "single core", "arquitetura", "xtensa", "risc-v", "riscv", "processor"], pinoRotulo: "" },
|
||||
{ id: "frequencia", nome: "Frequency", termos: ["frequencia", "mhz", "velocidade", "desempenho", "performance", "frequency"], pinoRotulo: "" },
|
||||
{ id: "ferramentas", nome: "Tools / SDK", termos: ["esp-idf", "idf", "arduino", "sdk", "toolchain", "versao do idf", "tools"], pinoRotulo: "" },
|
||||
{ id: "encapsulamento", nome: "Modules & Packaging", termos: ["modulo", "modulos", "encapsulamento", "package", "qfn", "wroom", "wrover", "mini-1", "modules"], pinoRotulo: "" },
|
||||
];
|
||||
|
||||
/**
|
||||
* Campos de public/series.json que respondem a cada assunto.
|
||||
* `campo` aceita caminho com ponto (seguranca.aes). `secao` é o id da âncora
|
||||
* na página /series/[key].
|
||||
*/
|
||||
export const SPEC_CAMPOS = [
|
||||
{ campo: "arquitetura", label: "Architecture", secao: "processador", topicos: ["processador"] },
|
||||
{ campo: "nucleos", label: "Cores", secao: "processador", topicos: ["processador"] },
|
||||
{ campo: "frequencia", label: "Frequency", secao: "processador", topicos: ["frequencia", "processador"] },
|
||||
{ campo: "coprocessador_ulp", label: "ULP Coprocessor", secao: "processador", topicos: ["baixo_consumo"] },
|
||||
{ campo: "aceleradores_ia", label: "AI Accelerators", secao: "processador", topicos: ["ia"] },
|
||||
|
||||
{ campo: "wifi", label: "Wi-Fi", secao: "conectividade", topicos: ["wifi"] },
|
||||
{ campo: "bluetooth", label: "Bluetooth", secao: "conectividade", topicos: ["bluetooth"] },
|
||||
{ campo: "zigbee_thread", label: "Zigbee/Thread", secao: "conectividade", topicos: ["zigbee"] },
|
||||
{ campo: "matter", label: "Matter", secao: "conectividade", topicos: ["matter"] },
|
||||
{ campo: "ethernet", label: "Ethernet", secao: "conectividade", topicos: ["ethernet"] },
|
||||
{ campo: "ethernet_mac", label: "Ethernet MAC", secao: "conectividade", topicos: ["ethernet"] },
|
||||
{ campo: "can", label: "CAN", secao: "conectividade", topicos: ["can"] },
|
||||
|
||||
{ campo: "memoria_sram", label: "SRAM", secao: "memoria", topicos: ["memoria"] },
|
||||
{ campo: "memoria_sram_rtc", label: "RTC SRAM", secao: "memoria", topicos: ["memoria", "baixo_consumo"] },
|
||||
{ campo: "memoria_rom", label: "ROM", secao: "memoria", topicos: ["memoria"] },
|
||||
{ campo: "flash_externa", label: "External Flash", secao: "memoria", topicos: ["flash", "memoria"] },
|
||||
{ campo: "psram_externa", label: "External PSRAM", secao: "memoria", topicos: ["psram", "memoria"] },
|
||||
|
||||
{ campo: "gpio", label: "GPIO", secao: "perifericos", topicos: ["gpio"] },
|
||||
{ campo: "adc", label: "ADC", secao: "perifericos", topicos: ["adc"] },
|
||||
{ campo: "dac", label: "DAC", secao: "perifericos", topicos: ["dac"] },
|
||||
{ campo: "touch", label: "Touch", secao: "perifericos", topicos: ["touch"] },
|
||||
{ campo: "uart", label: "UART", secao: "perifericos", topicos: ["uart"] },
|
||||
{ campo: "spi", label: "SPI", secao: "perifericos", topicos: ["spi", "flash"] },
|
||||
{ campo: "i2c", label: "I2C", secao: "perifericos", topicos: ["i2c"] },
|
||||
{ campo: "i2s", label: "I2S", secao: "perifericos", topicos: ["i2s"] },
|
||||
{ campo: "pwm", label: "PWM", secao: "perifericos", topicos: ["pwm"] },
|
||||
{ campo: "usb", label: "USB", secao: "perifericos", topicos: ["usb"] },
|
||||
{ campo: "lcd", label: "LCD", secao: "interfaces", topicos: ["lcd"] },
|
||||
{ campo: "camera", label: "Camera", secao: "interfaces", topicos: ["camera"] },
|
||||
{ campo: "mipi_csi", label: "MIPI CSI", secao: "interfaces", topicos: ["camera"] },
|
||||
{ campo: "mipi_dsi", label: "MIPI DSI", secao: "interfaces", topicos: ["lcd"] },
|
||||
{ campo: "sdio", label: "SDIO", secao: "interfaces", topicos: ["sd"] },
|
||||
{ campo: "sensor_temperatura", label: "Temperature Sensor", secao: "interfaces", topicos: ["temperatura"] },
|
||||
|
||||
{ campo: "seguranca.aes", label: "AES", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.sha", label: "SHA", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.rsa", label: "RSA", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.ecc", label: "ECC", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.ecdsa", label: "ECDSA", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.hmac", label: "HMAC", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.assinatura_digital", label: "Digital Signature", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.rng", label: "Random Number Generator", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.criptografia_flash", label: "Flash Encryption", secao: "seguranca", topicos: ["seguranca", "flash"] },
|
||||
{ campo: "seguranca.secure_boot", label: "Secure Boot", secao: "seguranca", topicos: ["seguranca", "strapping"] },
|
||||
|
||||
{ campo: "temperatura_operacao", label: "Operating Temperature", secao: "temperatura", topicos: ["temperatura"] },
|
||||
{ campo: "temperatura_armazenamento", label: "Storage Temperature", secao: "temperatura", topicos: ["temperatura"] },
|
||||
|
||||
{ campo: "esp_idf_minimo", label: "Minimum ESP-IDF", secao: "ferramentas", topicos: ["ferramentas"] },
|
||||
{ campo: "arduino_core", label: "Arduino Core", secao: "ferramentas", topicos: ["ferramentas"] },
|
||||
{ campo: "depuracao", label: "Debugging", secao: "ferramentas", topicos: ["jtag", "ferramentas"] },
|
||||
{ campo: "encapsulamento", label: "Package", secao: "ferramentas", topicos: ["encapsulamento"] },
|
||||
{ campo: "modulos", label: "Modules", secao: "ferramentas", topicos: ["encapsulamento"] },
|
||||
];
|
||||
|
||||
const ROTULOS_ENERGIA = {
|
||||
active: "Active",
|
||||
modem_sleep: "Modem Sleep",
|
||||
light_sleep: "Light Sleep",
|
||||
deep_sleep: "Deep Sleep",
|
||||
hibernation: "Hibernation",
|
||||
};
|
||||
|
||||
const pegar = (obj, caminho) => caminho.split(".").reduce((o, k) => (o == null ? o : o[k]), obj);
|
||||
|
||||
/**
|
||||
* Monta, para cada série, a lista plana de especificações (com os assuntos a
|
||||
* que respondem) e os pinos do diagrama. É o que o navegador baixa.
|
||||
*
|
||||
* @param {Record<string, object>} series conteúdo de public/series.json
|
||||
* @param {Record<string, object[]>} conexoes pinos por série (public/conexoes)
|
||||
*/
|
||||
export function montarConhecimento(series, conexoes) {
|
||||
const saida = {};
|
||||
for (const [chave, s] of Object.entries(series)) {
|
||||
const specs = [];
|
||||
for (const c of SPEC_CAMPOS) {
|
||||
const valor = pegar(s, c.campo);
|
||||
if (valor == null || valor === "") continue;
|
||||
specs.push({ label: c.label, valor: String(valor), secao: c.secao, topicos: c.topicos });
|
||||
}
|
||||
for (const [modo, valor] of Object.entries(s.consumo_energia ?? {})) {
|
||||
const base = modo.replace(/_cpu.*|_wifi.*/, "");
|
||||
const label = ROTULOS_ENERGIA[modo] ?? ROTULOS_ENERGIA[base] ?? modo.replace(/_/g, " ");
|
||||
specs.push({ label: `Consumo: ${label}`, valor: String(valor), secao: "energia", topicos: ["consumo"] });
|
||||
}
|
||||
saida[chave] = {
|
||||
nome: s.nome_completo ?? chave,
|
||||
specs,
|
||||
pinos: (conexoes[chave] ?? []).map((p) => ({
|
||||
n: String(p.numero),
|
||||
nome: p.nome,
|
||||
f: p.funcoes ?? [],
|
||||
c: p.categorias ?? [],
|
||||
a: p.avisos ?? [],
|
||||
})),
|
||||
};
|
||||
}
|
||||
return saida;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Carregadores de dados organizados por locale (seção 6.2 da spec).
|
||||
* Suporta pt, en, es, fr, de, zh-CN com fallback para pt.
|
||||
*/
|
||||
|
||||
export async function getSeries(locale = "pt") {
|
||||
try {
|
||||
return (await import(`@/data/${locale}/series.json`)).default;
|
||||
} catch {
|
||||
return (await import("@/data/pt/series.json")).default;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getFrameworks(locale = "pt") {
|
||||
try {
|
||||
return (await import(`@/data/${locale}/frameworks.json`)).default;
|
||||
} catch {
|
||||
return (await import("@/data/pt/frameworks.json")).default;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getConexoes(key, locale = "pt") {
|
||||
try {
|
||||
return (await import(`@/data/${locale}/conexoes/${key}.json`)).default;
|
||||
} catch {
|
||||
try {
|
||||
return (await import(`@/data/pt/conexoes/${key}.json`)).default;
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function getGlossario(locale = "pt") {
|
||||
try {
|
||||
return await import(`@/lib/data/${locale}/glossario.js`);
|
||||
} catch {
|
||||
return await import("@/lib/data/pt/glossario.js");
|
||||
}
|
||||
}
|
||||
|
||||
export async function getDiagnostico(locale = "pt") {
|
||||
try {
|
||||
return await import(`@/lib/data/${locale}/diagnostico.js`);
|
||||
} catch {
|
||||
return await import("@/lib/data/pt/diagnostico.js");
|
||||
}
|
||||
}
|
||||
|
||||
export async function getComponentes(locale = "pt") {
|
||||
try {
|
||||
return await import(`@/lib/data/${locale}/componentes.js`);
|
||||
} catch {
|
||||
return await import("@/lib/data/pt/componentes.js");
|
||||
}
|
||||
}
|
||||
|
||||
export async function getTopicos(locale = "pt") {
|
||||
try {
|
||||
return await import(`@/lib/data/${locale}/topicos.js`);
|
||||
} catch {
|
||||
return await import("@/lib/data/pt/topicos.js");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,858 @@
|
||||
/**
|
||||
* Base de Dados Oficial Curada: ESP Component Registry & IDF Component Manager
|
||||
*
|
||||
* O ESP Component Registry (https://components.espressif.com) é o ecossistema
|
||||
* central de distribuição de bibliotecas modulares para o ESP-IDF v4.4+ / v5.x+.
|
||||
*/
|
||||
|
||||
export const CATEGORIAS_COMPONENTES = [
|
||||
{
|
||||
id: "todos",
|
||||
nome: "Todos os Componentes",
|
||||
icone: "Layers",
|
||||
descricao: "Explore todo o catálogo curado de bibliotecas e drivers"
|
||||
},
|
||||
{
|
||||
id: "ui_display",
|
||||
nome: "UI, Displays & Gráficos",
|
||||
icone: "Monitor",
|
||||
descricao: "Bibliotecas gráficas (LVGL), drivers de display LCD/OLED, touch e decodificadores"
|
||||
},
|
||||
{
|
||||
id: "cloud_conectividade",
|
||||
nome: "Cloud & Conectividade",
|
||||
icone: "Cloud",
|
||||
descricao: "ESP RainMaker, AWS IoT, MQTT, WebSockets, Mesh-Lite e coprocessamento ESP-Hosted"
|
||||
},
|
||||
{
|
||||
id: "audio_voz_ia",
|
||||
nome: "Áudio, Voz & IA",
|
||||
icone: "Brain",
|
||||
descricao: "Reconhecimento de fala ESP-SR, processamento DSP, codecs, câmeras DVP e TinyML"
|
||||
},
|
||||
{
|
||||
id: "smart_home_mesh",
|
||||
nome: "Smart Home & Mesh",
|
||||
icone: "Home",
|
||||
descricao: "Matter SDK, pilhas Zigbee 3.0 (ZBOSS), Thread e redes ESP-NOW"
|
||||
},
|
||||
{
|
||||
id: "drivers_perifericos",
|
||||
nome: "Drivers & Sensores",
|
||||
icone: "Cpu",
|
||||
descricao: "Botões, encoders, LEDs RGB, Ethernet (W5500/CH390), USB nativo e sensores ambientais/IMU"
|
||||
},
|
||||
{
|
||||
id: "bsp_placas",
|
||||
nome: "BSPs (Board Support Packages)",
|
||||
icone: "CircuitBoard",
|
||||
descricao: "Pacotes de suporte direto para placas oficiais como ESP-BOX-3, Korvo, EYE e M5Stack"
|
||||
},
|
||||
{
|
||||
id: "sistema_utilitarios",
|
||||
nome: "Sistema & Utilitários",
|
||||
icone: "Wrench",
|
||||
descricao: "Sistemas de arquivos LittleFS, wrappers C++ modernos, CBOR e utilitários de rede"
|
||||
}
|
||||
];
|
||||
|
||||
export const COMPONENTES_REGISTRY = [
|
||||
// ==========================================
|
||||
// 1. UI, Displays & Gráficos
|
||||
// ==========================================
|
||||
{
|
||||
id: "espressif-esp_lvgl_port",
|
||||
namespace: "espressif",
|
||||
name: "esp_lvgl_port",
|
||||
versao: "^2.4.0",
|
||||
categoria: "ui_display",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP LVGL Port",
|
||||
descricao: "Port oficial e thread-safe do LVGL (Light and Versatile Graphics Library) para ESP-IDF com aceleração por hardware e suporte multi-display.",
|
||||
tags: ["LVGL", "GUI", "Display", "Touch", "IHM"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-P4", "ESP32-C3", "ESP32-C6"],
|
||||
dependenciasSugeridas: ["lvgl/lvgl^9.1.0"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_lvgl_port",
|
||||
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/components/esp_lvgl_port",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_lvgl_port: "^2.4.0"
|
||||
lvgl/lvgl: "^9.1.0"`
|
||||
},
|
||||
{
|
||||
id: "lvgl-lvgl",
|
||||
namespace: "lvgl",
|
||||
name: "lvgl",
|
||||
versao: "^9.1.0",
|
||||
categoria: "ui_display",
|
||||
oficial: false,
|
||||
popular: true,
|
||||
titulo: "LVGL Graphics Library Core",
|
||||
descricao: "Biblioteca gráfica de código aberto em C mais popular para sistemas embarcados. Fornece widgets ricos, animações fluidas e suporte a layouts modernos.",
|
||||
tags: ["LVGL 9", "Graphics", "Widgets", "GUI", "Embedded UI"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-P4", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/lvgl/lvgl",
|
||||
urlRepo: "https://github.com/lvgl/lvgl",
|
||||
exemploYaml: `dependencies:
|
||||
lvgl/lvgl: "^9.1.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp32_display_panel",
|
||||
namespace: "espressif",
|
||||
name: "esp32_display_panel",
|
||||
versao: "^0.2.0",
|
||||
categoria: "ui_display",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP32 Display Panel Driver",
|
||||
descricao: "Driver unificado de controladores LCD (RGB, SPI, QSPI, MIPI-DSI) e touch capacitivo desenhado especialmente para ESP32-S3 e ESP32-P4.",
|
||||
tags: ["LCD", "MIPI-DSI", "QSPI", "Touch", "ST7789", "ILI9341"],
|
||||
chips: ["ESP32-S3", "ESP32-P4", "ESP32-S2", "ESP32"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp32_display_panel",
|
||||
urlRepo: "https://github.com/esp-arduino-libs/ESP32_Display_Panel",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp32_display_panel: "^0.2.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_lcd_touch",
|
||||
namespace: "espressif",
|
||||
name: "esp_lcd_touch",
|
||||
versao: "^1.1.2",
|
||||
categoria: "ui_display",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP LCD Touch Framework",
|
||||
descricao: "Componente central de abstração de painéis touch para telas LCD. Suporta calibragem de coordenadas, leitura de múltiplos toques e integração direta com LVGL.",
|
||||
tags: ["Touchscreen", "Capacitivo", "Resistivo", "I2C Touch", "Coordenadas"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-P4", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_lcd_touch",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/display/touch_panel/esp_lcd_touch",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_lcd_touch: "^1.1.2"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_lcd_touch_gt911",
|
||||
namespace: "espressif",
|
||||
name: "esp_lcd_touch_gt911",
|
||||
versao: "^1.1.2",
|
||||
categoria: "ui_display",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "Driver Touch Capacitivo GT911",
|
||||
descricao: "Driver I2C especializado para o controlador de touch capacitivo Goodix GT911, amplamente utilizado em displays de 4.3\", 5\" e 7\" para ESP32-S3 e P4.",
|
||||
tags: ["GT911", "Goodix", "Touch Capacitivo", "Multitouch", "I2C"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-S2"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_lcd_touch_gt911",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/display/touch_panel/esp_lcd_touch_gt911",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_lcd_touch_gt911: "^1.1.2"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_lcd_touch_ft5x06",
|
||||
namespace: "espressif",
|
||||
name: "esp_lcd_touch_ft5x06",
|
||||
versao: "^1.1.0",
|
||||
categoria: "ui_display",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "Driver Touch FocalTech FT5x06 / FT6x36",
|
||||
descricao: "Driver de painel touch capacitivo para controladores FocalTech (FT5206, FT5316, FT5436, FT6236, FT6336) com suporte a gestos e interrupções.",
|
||||
tags: ["FT6236", "FT5x06", "FocalTech", "Touch", "I2C"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-S2", "ESP32-C3"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_lcd_touch_ft5x06",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/display/touch_panel/esp_lcd_touch_ft5x06",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_lcd_touch_ft5x06: "^1.1.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_jpeg",
|
||||
namespace: "espressif",
|
||||
name: "esp_jpeg",
|
||||
versao: "^1.3.0",
|
||||
categoria: "ui_display",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "ESP JPEG Decoder (TJpgDec)",
|
||||
descricao: "Decodificador e codificador JPEG de alta velocidade com otimizações SIMD em Assembly para exibir imagens e streams de câmeras em displays sem atrasos.",
|
||||
tags: ["JPEG", "TJpgDec", "Câmera", "Imagem", "SIMD"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-C3"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_jpeg",
|
||||
urlRepo: "https://github.com/espressif/esp-jpeg",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_jpeg: "^1.3.0"`
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// 2. Cloud & Conectividade
|
||||
// ==========================================
|
||||
{
|
||||
id: "espressif-esp_rainmaker",
|
||||
namespace: "espressif",
|
||||
name: "esp_rainmaker",
|
||||
versao: "^1.4.0",
|
||||
categoria: "cloud_conectividade",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP RainMaker Agent",
|
||||
descricao: "Agente oficial de firmware para a plataforma de nuvem AIoT ESP RainMaker. Habilita controle por app móvel, Alexa, Google Home e OTA.",
|
||||
tags: ["RainMaker", "AWS Cloud", "App iOS/Android", "Alexa", "Google Home", "OTA"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_rainmaker",
|
||||
urlRepo: "https://github.com/espressif/esp-rainmaker",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_rainmaker: "^1.4.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-mesh_lite",
|
||||
namespace: "espressif",
|
||||
name: "mesh_lite",
|
||||
versao: "^1.2.0",
|
||||
categoria: "cloud_conectividade",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP Mesh-Lite Network Stack",
|
||||
descricao: "Rede em malha Wi-Fi leve onde cada nó possui conectividade IP independente, permitindo comunicação direta na rede local e acesso à nuvem com múltiplos saltos.",
|
||||
tags: ["Mesh", "Wi-Fi Mesh", "Rede em Malha", "IoT Distribuída", "IP Layer"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/mesh_lite",
|
||||
urlRepo: "https://github.com/espressif/esp-mesh-lite",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/mesh_lite: "^1.2.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_modbus",
|
||||
namespace: "espressif",
|
||||
name: "esp_modbus",
|
||||
versao: "^1.0.15",
|
||||
categoria: "cloud_conectividade",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP-Modbus Industrial Stack",
|
||||
descricao: "Implementação completa da pilha industrial Modbus (Master/Slave) suportando interfaces RS-485 (RTU/ASCII) e Ethernet/Wi-Fi (Modbus TCP).",
|
||||
tags: ["Modbus", "RS-485", "Modbus TCP", "Automação Industrial", "PLC"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_modbus",
|
||||
urlRepo: "https://github.com/espressif/esp-modbus",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_modbus: "^1.0.15"`
|
||||
},
|
||||
{
|
||||
id: "espressif-net_connect",
|
||||
namespace: "espressif",
|
||||
name: "net_connect",
|
||||
versao: "^1.0.0",
|
||||
categoria: "cloud_conectividade",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "Unified Network Connect",
|
||||
descricao: "Componente unificado de gerenciamento de conexão de rede, alternando e inicializando de forma transparente Wi-Fi, Ethernet, Thread ou PPP móvel.",
|
||||
tags: ["Network", "Wi-Fi", "Ethernet", "Fallback", "Conexão Automática"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/net_connect",
|
||||
urlRepo: "https://github.com/espressif/esp-idf/tree/master/components",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/net_connect: "^1.0.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_hosted",
|
||||
namespace: "espressif",
|
||||
name: "esp_hosted",
|
||||
versao: "^0.0.10",
|
||||
categoria: "cloud_conectividade",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "ESP-Hosted Coprocessor",
|
||||
descricao: "Transforma o ESP32 em um coprocessador de comunicação sem fio (Wi-Fi + BLE) para hosts Linux (Raspberry Pi, i.MX) ou microcontroladores via SPI/SDIO/UART.",
|
||||
tags: ["Coprocessador", "SDIO", "SPI", "Linux Wi-Fi", "Raspberry Pi"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_hosted",
|
||||
urlRepo: "https://github.com/espressif/esp-hosted",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_hosted: "^0.0.10"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp-now",
|
||||
namespace: "espressif",
|
||||
name: "esp-now",
|
||||
versao: "^2.5.0",
|
||||
categoria: "cloud_conectividade",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP-NOW Enhanced & Provisioning",
|
||||
descricao: "Extensão com recursos avançados de emparelhamento por controle remoto, segurança AES-128 e controle de múltiplos dispositivos com protocolo ESP-NOW.",
|
||||
tags: ["ESP-NOW", "Sem Fio", "Baixa Latência", "Broadcast", "Controle Remoto"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-now",
|
||||
urlRepo: "https://github.com/espressif/esp-now",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-now: "^2.5.0"`
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// 3. Áudio, Voz & IA
|
||||
// ==========================================
|
||||
{
|
||||
id: "espressif-esp-sr",
|
||||
namespace: "espressif",
|
||||
name: "esp-sr",
|
||||
versao: "^1.5.0",
|
||||
categoria: "audio_voz_ia",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP-SR Speech Recognition",
|
||||
descricao: "Framework de reconhecimento de fala 100% offline com WakeNet (palavra de ativação), MultiNet (comandos locais) e algoritmos acústicos AFE.",
|
||||
tags: ["Voz", "WakeNet", "MultiNet", "Reconhecimento de Fala", "Offline", "AEC"],
|
||||
chips: ["ESP32-S3", "ESP32-P4", "ESP32"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-sr",
|
||||
urlRepo: "https://github.com/espressif/esp-sr",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-sr: "^1.5.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_codec_dev",
|
||||
namespace: "espressif",
|
||||
name: "esp_codec_dev",
|
||||
versao: "^1.3.0",
|
||||
categoria: "audio_voz_ia",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP Audio Codec Device HAL",
|
||||
descricao: "Camada unificada de abstração de codecs de áudio I2S/I2C (ES8311, ES8388, ES7210, ES7243, TAS5805M) para entrada e saída de som estéreo.",
|
||||
tags: ["Audio Codec", "I2S", "ES8311", "ES8388", "Microfone DAC"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_codec_dev",
|
||||
urlRepo: "https://github.com/espressif/esp-codec-dev",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_codec_dev: "^1.3.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-es8311",
|
||||
namespace: "espressif",
|
||||
name: "es8311",
|
||||
versao: "^1.0.0",
|
||||
categoria: "audio_voz_ia",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "Driver Codec de Áudio ES8311",
|
||||
descricao: "Driver dedicado de baixo consumo para o codec Everest ES8311 (DAC mono + ADC de microfone) presente no ESP32-S3-BOX e placas de IoT.",
|
||||
tags: ["ES8311", "Áudio", "DAC", "Microfone", "I2S"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-C3"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/es8311",
|
||||
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/components/es8311",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/es8311: "^1.0.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp32-camera",
|
||||
namespace: "espressif",
|
||||
name: "esp32-camera",
|
||||
versao: "^2.0.12",
|
||||
categoria: "audio_voz_ia",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP32 Camera Driver",
|
||||
descricao: "Driver oficial de câmeras CMOS (OV2640, OV3660, OV5640, OV7670, GC0308) com suporte a DMA, DMA-2D, captura JPEG e streaming MJPEG por HTTP/RTSP.",
|
||||
tags: ["Câmera", "OV2640", "OV5640", "DVP", "MIPI-CSI", "Vídeo"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-S2"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp32-camera",
|
||||
urlRepo: "https://github.com/espressif/esp32-camera",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp32-camera: "^2.0.12"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp-dsp",
|
||||
namespace: "espressif",
|
||||
name: "esp-dsp",
|
||||
versao: "^1.5.1",
|
||||
categoria: "audio_voz_ia",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP-DSP Signal Processing",
|
||||
descricao: "Biblioteca oficial de processamento digital de sinais para SoCs ESP32 (FFT, filtros digitais FIR/IIR, matrizes e álgebra linear acelerada).",
|
||||
tags: ["DSP", "FFT", "Filtros", "Matemática", "SIMD", "Assembly"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-P4", "ESP32-C3", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-dsp",
|
||||
urlRepo: "https://github.com/espressif/esp-dsp",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-dsp: "^1.5.1"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp-nn",
|
||||
namespace: "espressif",
|
||||
name: "esp-nn",
|
||||
versao: "^1.2.0",
|
||||
categoria: "audio_voz_ia",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP-NN Neural Network Kernels",
|
||||
descricao: "Kernels otimizados em assembly vetorial para aceleração de redes neurais e modelos TensorFlow Lite Micro em chips ESP32.",
|
||||
tags: ["TinyML", "TensorFlow Lite", "Redes Neurais", "Inferência", "Edge AI"],
|
||||
chips: ["ESP32-S3", "ESP32-P4", "ESP32"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-nn",
|
||||
urlRepo: "https://github.com/espressif/esp-nn",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-nn: "^1.2.0"`
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// 4. Smart Home & Mesh
|
||||
// ==========================================
|
||||
{
|
||||
id: "espressif-esp-matter",
|
||||
namespace: "espressif",
|
||||
name: "esp-matter",
|
||||
versao: "^1.3.0",
|
||||
categoria: "smart_home_mesh",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP Matter SDK",
|
||||
descricao: "SDK oficial para criar dispositivos interoperáveis com Apple Home, Google Home, Amazon Alexa e Home Assistant sobre Wi-Fi e Thread.",
|
||||
tags: ["Matter", "Smart Home", "Apple HomeKit", "Google Home", "Thread", "CHIP"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-H2"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-matter",
|
||||
urlRepo: "https://github.com/espressif/esp-matter",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-matter: "^1.3.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp-zigbee-lib",
|
||||
namespace: "espressif",
|
||||
name: "esp-zigbee-lib",
|
||||
versao: "^1.6.0",
|
||||
categoria: "smart_home_mesh",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP Zigbee 3.0 Library",
|
||||
descricao: "Pilha certificada Zigbee 3.0 (ZBOSS) para criação de nós Coordenadores, Roteadores e Dispositivos Finais de baixo consumo em chips 802.15.4.",
|
||||
tags: ["Zigbee 3.0", "ZBOSS", "802.15.4", "Home Automation", "Bateria"],
|
||||
chips: ["ESP32-H2", "ESP32-C6"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-zigbee-lib",
|
||||
urlRepo: "https://github.com/espressif/esp-zigbee-sdk",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-zigbee-lib: "^1.6.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_rcp_update",
|
||||
namespace: "espressif",
|
||||
name: "esp_rcp_update",
|
||||
versao: "^1.0.0",
|
||||
categoria: "smart_home_mesh",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "ESP RCP Thread/Zigbee Gateway",
|
||||
descricao: "Componente para atualização de coprocessador de rádio (RCP) 802.15.4 para construção de Thread Border Routers e gateways Zigbee multiprotocolo.",
|
||||
tags: ["Thread Border Router", "OpenThread", "RCP", "Zigbee Gateway"],
|
||||
chips: ["ESP32-H2", "ESP32-C6", "ESP32-S3"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_rcp_update",
|
||||
urlRepo: "https://github.com/espressif/esp-thread-br",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_rcp_update: "^1.0.0"`
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// 5. Drivers & Sensores
|
||||
// ==========================================
|
||||
{
|
||||
id: "espressif-led_indicator",
|
||||
namespace: "espressif",
|
||||
name: "led_indicator",
|
||||
versao: "^1.2.0",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "LED Indicator Driver",
|
||||
descricao: "Driver inteligente para controle de padrões de iluminação de LED (piscar rápido, respiração/fade, códigos de erro e RGB) sem travar o loop principal.",
|
||||
tags: ["LED", "PWM", "RGB", "Blink", "Feedback Visual"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C2", "ESP32-C3", "ESP32-C6", "ESP32-H2", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/led_indicator",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/led/led_indicator",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/led_indicator: "^1.2.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-button",
|
||||
namespace: "espressif",
|
||||
name: "button",
|
||||
versao: "^3.4.0",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "IoT Button Handler (iot_button)",
|
||||
descricao: "Gerenciador completo de botões com debounce, eventos de clique único, duplo, múltiplo, pressionamento longo e matrizes de teclado.",
|
||||
tags: ["Botão", "Debounce", "Long Press", "Double Click", "GPIO"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-H2", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/button",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/button",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/button: "^3.4.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-led_strip",
|
||||
namespace: "espressif",
|
||||
name: "led_strip",
|
||||
versao: "^2.5.4",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "Addressable LED Strip (WS2812/SK6812)",
|
||||
descricao: "Driver de alto desempenho para fitas e matrizes de LED endereçáveis WS2812, WS2813 e SK6812 usando periféricos RMT ou SPI.",
|
||||
tags: ["WS2812B", "Neopixel", "SK6812", "RMT", "Fita de LED", "RGB"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/led_strip",
|
||||
urlRepo: "https://github.com/espressif/idf-extra-components/tree/master/led_strip",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/led_strip: "^2.5.4"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_tinyusb",
|
||||
namespace: "espressif",
|
||||
name: "esp_tinyusb",
|
||||
versao: "^1.5.0",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP Native USB Device (TinyUSB)",
|
||||
descricao: "Extensão oficial do TinyUSB para ESP32-S2, ESP32-S3 e ESP32-P4, permitindo emular portas seriais USB CDC, Teclado/Mouse HID, Pen Drive MSC, DFU e WebUSB.",
|
||||
tags: ["USB Nativo", "TinyUSB", "USB CDC", "USB HID", "WebUSB", "MSC"],
|
||||
chips: ["ESP32-S2", "ESP32-S3", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_tinyusb",
|
||||
urlRepo: "https://github.com/espressif/esp-tinyusb",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_tinyusb: "^1.5.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-w5500",
|
||||
namespace: "espressif",
|
||||
name: "w5500",
|
||||
versao: "^1.2.0",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "WIZnet W5500 SPI Ethernet Driver",
|
||||
descricao: "Driver oficial para o chip Ethernet WIZnet W5500 via barramento SPI, integrando perfeitamente a interface física à pilha TCP/IP (lwIP) nativa do ESP-IDF.",
|
||||
tags: ["W5500", "Ethernet", "SPI Ethernet", "RJ45", "lwIP", "Rede Cabeada"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/w5500",
|
||||
urlRepo: "https://github.com/espressif/esp-eth-drivers/tree/master/w5500",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/w5500: "^1.2.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-ch390",
|
||||
namespace: "espressif",
|
||||
name: "ch390",
|
||||
versao: "^1.0.0",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "CH390 SPI Ethernet Driver",
|
||||
descricao: "Driver SPI Ethernet 10/100M para o controlador WCH CH390, ideal para adicionar porta de rede RJ45 econômica em placas com ESP32-C3, S3 ou P4.",
|
||||
tags: ["CH390", "Ethernet", "WCH", "SPI Ethernet", "RJ45"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/ch390",
|
||||
urlRepo: "https://github.com/espressif/esp-eth-drivers/tree/master/ch390",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/ch390: "^1.0.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-usb_host_uvc",
|
||||
namespace: "espressif",
|
||||
name: "usb_host_uvc",
|
||||
versao: "^1.0.4",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "USB Host UVC (Webcam Driver)",
|
||||
descricao: "Driver USB Host para conectar webcams USB UVC padrão diretamente na porta USB nativa do ESP32-S2, ESP32-S3 ou ESP32-P4.",
|
||||
tags: ["USB Host", "UVC", "Webcam", "Câmera USB", "Vídeo"],
|
||||
chips: ["ESP32-S2", "ESP32-S3", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/usb_host_uvc",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/usb/usb_host_uvc",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/usb_host_uvc: "^1.0.4"`
|
||||
},
|
||||
{
|
||||
id: "espressif-sensor_hub",
|
||||
namespace: "espressif",
|
||||
name: "sensor_hub",
|
||||
versao: "^1.0.0",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "ESP Sensor Hub Manager",
|
||||
descricao: "Framework unificado para gerenciamento de sensores heterogêneos (I2C/SPI) com amostragem periódica, fusão de dados e disparo por eventos/interrupções.",
|
||||
tags: ["Sensores", "Sensor Hub", "I2C", "Eventos", "Coleta Periódica"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/sensor_hub",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/sensors/sensor_hub",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/sensor_hub: "^1.0.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-bmi270_sensor",
|
||||
namespace: "espressif",
|
||||
name: "bmi270_sensor",
|
||||
versao: "^1.0.1",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "Driver Sensor IMU Bosch BMI270",
|
||||
descricao: "Driver oficial para o sensor inercial IMU de 6 eixos Bosch BMI270 (Acelerômetro + Giroscópio) com detecção de gestos de movimento e passos.",
|
||||
tags: ["BMI270", "IMU", "Acelerômetro", "Giroscópio", "Bosch", "Gestos"],
|
||||
chips: ["ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/bmi270_sensor",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/sensors/imu/bmi270",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/bmi270_sensor: "^1.0.1"`
|
||||
},
|
||||
{
|
||||
id: "espressif-ds18b20",
|
||||
namespace: "espressif",
|
||||
name: "ds18b20",
|
||||
versao: "^1.0.0",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "Driver Sensor de Temperatura DS18B20",
|
||||
descricao: "Driver digital para sensor de temperatura 1-Wire Dallas/Maxim DS18B20 com suporte a múltiplos sensores no mesmo pino GPIO via barramento RMT.",
|
||||
tags: ["DS18B20", "1-Wire", "Temperatura", "Sensor", "Dallas"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/ds18b20",
|
||||
urlRepo: "https://github.com/espressif/esp-iot-solution/tree/master/components/sensors/temperature/ds18b20",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/ds18b20: "^1.0.0"`
|
||||
},
|
||||
{
|
||||
id: "esp-idf-lib-scd4x",
|
||||
namespace: "esp-idf-lib",
|
||||
name: "scd4x",
|
||||
versao: "^1.0.0",
|
||||
categoria: "drivers_perifericos",
|
||||
oficial: false,
|
||||
popular: true,
|
||||
titulo: "Driver Sensor CO2 Sensirion SCD40/SCD41",
|
||||
descricao: "Driver I2C de alta precisão para sensores fotoacústicos de CO2, temperatura e umidade relativa Sensirion SCD40 e SCD41 com auto-calibragem.",
|
||||
tags: ["SCD40", "SCD41", "Sensirion", "CO2", "Qualidade do Ar", "I2C"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-H2", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/esp-idf-lib/scd4x",
|
||||
urlRepo: "https://github.com/UncleRus/esp-idf-lib/tree/master/components/scd4x",
|
||||
exemploYaml: `dependencies:
|
||||
esp-idf-lib/scd4x: "^1.0.0"`
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// 6. BSPs (Board Support Packages)
|
||||
// ==========================================
|
||||
{
|
||||
id: "espressif-esp-box-3",
|
||||
namespace: "espressif",
|
||||
name: "esp-box-3",
|
||||
versao: "^1.2.0",
|
||||
categoria: "bsp_placas",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "BSP ESP32-S3-BOX-3",
|
||||
descricao: "Pacote de suporte completo para a placa de desenvolvimento de IA ESP32-S3-BOX-3, inicializando tela touch, codec de áudio, microfones duplos, sensor de movimento e LEDs com uma única função.",
|
||||
tags: ["BSP", "ESP-BOX-3", "Display Touch", "Microfone", "Áudio ES8311", "I2C/SPI"],
|
||||
chips: ["ESP32-S3"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-box-3",
|
||||
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/bsp/esp-box-3",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-box-3: "^1.2.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp32_s3_korvo_2",
|
||||
namespace: "espressif",
|
||||
name: "esp32_s3_korvo_2",
|
||||
versao: "^1.1.0",
|
||||
categoria: "bsp_placas",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "BSP ESP32-S3-Korvo-2",
|
||||
descricao: "Board Support Package para o kit de desenvolvimento de áudio e reconhecimento de voz ESP32-S3-Korvo-2, com suporte a microfones I2S e botões de toque.",
|
||||
tags: ["BSP", "Korvo", "Áudio", "Array de Microfones", "ESP-SR"],
|
||||
chips: ["ESP32-S3"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp32_s3_korvo_2",
|
||||
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_korvo_2",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp32_s3_korvo_2: "^1.1.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp32_s3_eye",
|
||||
namespace: "espressif",
|
||||
name: "esp32_s3_eye",
|
||||
versao: "^1.1.0",
|
||||
categoria: "bsp_placas",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "BSP ESP32-S3-EYE",
|
||||
descricao: "Board Support Package para a placa de visão computacional oficial ESP32-S3-EYE, configurando câmera OV2640, display LCD SPI redondo e microfone digital.",
|
||||
tags: ["BSP", "ESP32-S3-EYE", "Câmera", "Visão Computacional", "Display"],
|
||||
chips: ["ESP32-S3"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp32_s3_eye",
|
||||
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_eye",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp32_s3_eye: "^1.1.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-m5stack_core_s3",
|
||||
namespace: "espressif",
|
||||
name: "m5stack_core_s3",
|
||||
versao: "^1.0.0",
|
||||
categoria: "bsp_placas",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "BSP M5Stack CoreS3",
|
||||
descricao: "Board Support Package oficial para o dispositivo M5Stack CoreS3, inicializando tela sensível ao toque, PMIC AXP2101, câmera GC0308 e alto-falante I2S.",
|
||||
tags: ["BSP", "M5Stack", "CoreS3", "Display ILI9342C", "AXP2101", "Câmera"],
|
||||
chips: ["ESP32-S3"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/m5stack_core_s3",
|
||||
urlRepo: "https://github.com/espressif/esp-bsp/tree/master/bsp/m5stack_core_s3",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/m5stack_core_s3: "^1.0.0"`
|
||||
},
|
||||
{
|
||||
id: "waveshare-esp32_p4_wifi6_touch_lcd_7b",
|
||||
namespace: "waveshare",
|
||||
name: "esp32_p4_wifi6_touch_lcd_7b",
|
||||
versao: "^1.0.0",
|
||||
categoria: "bsp_placas",
|
||||
oficial: false,
|
||||
popular: true,
|
||||
titulo: "BSP Waveshare ESP32-P4 Touch LCD 7\"",
|
||||
descricao: "Pacote de suporte para a placa de alta performance Waveshare ESP32-P4 com tela touch capacitiva de 7 polegadas (MIPI-DSI 1024x600) e coprocessador Wi-Fi 6.",
|
||||
tags: ["BSP", "ESP32-P4", "MIPI-DSI", "Waveshare", "Tela 7 Polegadas", "Touch"],
|
||||
chips: ["ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/waveshare/esp32_p4_wifi6_touch_lcd_7b",
|
||||
urlRepo: "https://github.com/waveshare/ESP32-P4-WiFi6-Touch-LCD-7B",
|
||||
exemploYaml: `dependencies:
|
||||
waveshare/esp32_p4_wifi6_touch_lcd_7b: "^1.0.0"`
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// 7. Sistema & Utilitários
|
||||
// ==========================================
|
||||
{
|
||||
id: "joltwallet-littlefs",
|
||||
namespace: "joltwallet",
|
||||
name: "littlefs",
|
||||
versao: "^1.14.8",
|
||||
categoria: "sistema_utilitarios",
|
||||
oficial: false,
|
||||
popular: true,
|
||||
titulo: "LittleFS Filesystem for ESP-IDF",
|
||||
descricao: "Port robusto do sistema de arquivos LittleFS para memória Flash SPI com wear-leveling dinâmico e proteção contra corrupção por queda de energia.",
|
||||
tags: ["LittleFS", "Flash", "Filesystem", "Wear Leveling", "NVS"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-H2", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/joltwallet/littlefs",
|
||||
urlRepo: "https://github.com/joltwallet/esp_littlefs",
|
||||
exemploYaml: `dependencies:
|
||||
joltwallet/littlefs: "^1.14.8"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp-idf-cxx",
|
||||
namespace: "espressif",
|
||||
name: "esp-idf-cxx",
|
||||
versao: "^1.2.0",
|
||||
categoria: "sistema_utilitarios",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP-IDF C++ Idiomatic Wrappers",
|
||||
descricao: "Conjunto de classes e wrappers C++ modernos (C++17/C++20/C++23) com semântica RAII para GPIOs, Wi-Fi, timers, filas FreeRTOS e semáforos.",
|
||||
tags: ["C++", "C++20", "RAII", "Modern C++", "Object Oriented", "FreeRTOS"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-H2", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp-idf-cxx",
|
||||
urlRepo: "https://github.com/espressif/esp-idf-cxx",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp-idf-cxx: "^1.2.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-cbor",
|
||||
namespace: "espressif",
|
||||
name: "cbor",
|
||||
versao: "^0.6.0",
|
||||
categoria: "sistema_utilitarios",
|
||||
oficial: true,
|
||||
popular: false,
|
||||
titulo: "TinyCBOR Serialization",
|
||||
descricao: "Biblioteca ultraleve para serialização e deserialização de dados em formato binário CBOR (Concise Binary Object Representation).",
|
||||
tags: ["CBOR", "Serialização", "Binário", "IoT Protocol", "JSON Compacto"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-H2", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/cbor",
|
||||
urlRepo: "https://github.com/espressif/tinycbor",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/cbor: "^0.6.0"`
|
||||
},
|
||||
{
|
||||
id: "espressif-esp_websocket_client",
|
||||
namespace: "espressif",
|
||||
name: "esp_websocket_client",
|
||||
versao: "^1.2.4",
|
||||
categoria: "sistema_utilitarios",
|
||||
oficial: true,
|
||||
popular: true,
|
||||
titulo: "ESP WebSocket Client",
|
||||
descricao: "Cliente WebSocket bidirecional em tempo real com suporte a TLS/SSL (WSS), reconexão automática, sub-protocolos e ping/pong de heartbeat.",
|
||||
tags: ["WebSocket", "WSS", "TLS", "Tempo Real", "Sockets", "JSON"],
|
||||
chips: ["ESP32", "ESP32-S2", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4"],
|
||||
urlRegistry: "https://components.espressif.com/components/espressif/esp_websocket_client",
|
||||
urlRepo: "https://github.com/espressif/esp-protocols/tree/master/components/esp_websocket_client",
|
||||
exemploYaml: `dependencies:
|
||||
espressif/esp_websocket_client: "^1.2.4"`
|
||||
}
|
||||
];
|
||||
|
||||
export const GUIA_COMPONENT_MANAGER = {
|
||||
titulo: "Como Usar o ESP Component Registry no ESP-IDF",
|
||||
resumo: "A partir do ESP-IDF v4.4 e consolidado no v5.x+, a Espressif adotou a arquitetura de pacotes modulares gerenciada pelo IDF Component Manager. Esqueça submódulos git complexos: agora basta declarar as bibliotecas no arquivo de manifesto idf_component.yml do seu projeto.",
|
||||
vantagens: [
|
||||
{
|
||||
titulo: "Instalação Automática e Desacoplada",
|
||||
descricao: "O compilador baixa, compila e gerencia as versões das bibliotecas automaticamente durante o 'idf.py build' ou 'idf.py reconfigure'."
|
||||
},
|
||||
{
|
||||
titulo: "Versionamento Semântico Rigoroso",
|
||||
descricao: "Controle exatamente quando atualizar com operadores de versão (^ para compatibilidade minor, ~ para patches ou versões exatas fixas)."
|
||||
},
|
||||
{
|
||||
titulo: "Projetos mais Leves e Limpos",
|
||||
descricao: "O repositório do seu projeto fica limpo, sem carregar código de terceiros dentro do histórico do Git."
|
||||
},
|
||||
{
|
||||
titulo: "Compartilhamento Corporativo ou Comunitário",
|
||||
descricao: "Publique seus próprios componentes na nuvem pública da Espressif ou em registros privados locais da sua empresa."
|
||||
}
|
||||
],
|
||||
comandosCli: [
|
||||
{
|
||||
comando: 'idf.py add-dependency "namespace/componente^versao"',
|
||||
exemplo: 'idf.py add-dependency "espressif/esp_lvgl_port^2.4.0"',
|
||||
explicacao: "Cria ou atualiza automaticamente o arquivo 'main/idf_component.yml' adicionando a dependência informada."
|
||||
},
|
||||
{
|
||||
comando: "idf.py reconfigure",
|
||||
exemplo: "idf.py reconfigure",
|
||||
explicacao: "Força o CMake e o Component Manager a resolver novamente a árvore de dependências e baixar pacotes pendentes."
|
||||
},
|
||||
{
|
||||
comando: "compote component upload --name <component_name> --namespace <sua_org>",
|
||||
exemplo: "compote component upload --name meu_driver_sensor --namespace minhadiv",
|
||||
explicacao: "Publica seu componente de código aberto ou proprietário no ESP Component Registry usando a ferramenta oficial Compote CLI."
|
||||
}
|
||||
],
|
||||
sintaxeManifesto: `# Estrutura típica do arquivo: main/idf_component.yml
|
||||
dependencies:
|
||||
# Baixa do registro oficial da Espressif
|
||||
espressif/esp_lvgl_port: "^2.4.0"
|
||||
espressif/button: "~3.4.0"
|
||||
|
||||
# Versão exata
|
||||
espressif/led_indicator: "1.2.0"
|
||||
|
||||
# Dependência da comunidade
|
||||
joltwallet/littlefs: "^1.14.8"
|
||||
|
||||
# Dependência local no seu disco (opcional)
|
||||
# meu_driver_local:
|
||||
# path: "../../components/meu_driver"`
|
||||
};
|
||||
@@ -0,0 +1,743 @@
|
||||
/**
|
||||
* Base de dados estruturada para o Guia de Diagnóstico, Erros Comuns e Resolução de Problemas no ESP32.
|
||||
* Abrange 6 categorias técnicas com causas raízes, comparativos de boas práticas vs gambiarras e exemplos de código
|
||||
* em Arduino C++, ESP-IDF (C) e MicroPython.
|
||||
*/
|
||||
|
||||
export const categoriasDiagnostico = [
|
||||
{
|
||||
id: "alimentacao",
|
||||
nome: "Alimentação & Hardware",
|
||||
icone: "Zap",
|
||||
cor: "amber",
|
||||
descricao: "Quedas de tensão por picos de RF Wi-Fi/BLE, strapping pins conflitantes, ruído eletromagnético e problemas de LDO.",
|
||||
},
|
||||
{
|
||||
id: "cpu-panics",
|
||||
nome: "Pânicos de CPU & Guru Meditation",
|
||||
icone: "Cpu",
|
||||
cor: "red",
|
||||
descricao: "Ponteiros nulos, violações de memória (Load/StoreProhibited), instruções ilegais e cache panics em ISR.",
|
||||
},
|
||||
{
|
||||
id: "freertos",
|
||||
nome: "FreeRTOS & Multitarefa",
|
||||
icone: "Layers",
|
||||
cor: "purple",
|
||||
descricao: "Task Watchdog (TWDT), Interrupt Watchdog (IWDT), estouro de pilha (Stack Overflow) e bloqueios de escalonador.",
|
||||
},
|
||||
{
|
||||
id: "memoria",
|
||||
nome: "Memória, Heap & PSRAM",
|
||||
icone: "Activity",
|
||||
cor: "blue",
|
||||
descricao: "Fragmentação de Heap, vazamento de memória (Memory Leaks), alocações para DMA e limitações de PSRAM.",
|
||||
},
|
||||
{
|
||||
id: "boot-flash",
|
||||
nome: "Bootloader & Gravação",
|
||||
icone: "Terminal",
|
||||
cor: "emerald",
|
||||
descricao: "Falha de comunicação serial (DTR/RTS), erros de leitura SPI Flash, incompatibilidade de clock e partições.",
|
||||
},
|
||||
{
|
||||
id: "conectividade",
|
||||
nome: "Conectividade & Protocolos",
|
||||
icone: "Wifi",
|
||||
cor: "cyan",
|
||||
descricao: "Wi-Fi Beacon Timeout, falhas de handshake TLS/HTTPS por falta de relógio SNTP e instabilidade de sinal.",
|
||||
},
|
||||
];
|
||||
|
||||
export const sintomasRapidos = [
|
||||
{ id: "bootloop", rotulo: "🔄 Reiniciando em loop (Bootloop)", categoria: "todos" },
|
||||
{ id: "wifi-crash", rotulo: "📶 Trava ao ligar Wi-Fi/BLE", categoria: "alimentacao" },
|
||||
{ id: "upload-fail", rotulo: "🔌 Falha ao gravar código (Upload)", categoria: "boot-flash" },
|
||||
{ id: "random-freeze", rotulo: "⏱️ Trava após minutos/horas", categoria: "memoria" },
|
||||
{ id: "null-pointer", rotulo: "💥 Guru Meditation (Crash)", categoria: "cpu-panics" },
|
||||
{ id: "wdt-reset", rotulo: "🐕 Watchdog Triggered", categoria: "freertos" },
|
||||
{ id: "tls-fail", rotulo: "🔒 Falha em HTTPS / SSL", categoria: "conectividade" },
|
||||
];
|
||||
|
||||
export const errosCatalogo = [
|
||||
{
|
||||
id: "brownout-reset",
|
||||
titulo: "Brownout Detector Reset (Queda de Tensão)",
|
||||
categoria: "alimentacao",
|
||||
sintomas: ["bootloop", "wifi-crash"],
|
||||
gravidade: "Alta",
|
||||
logSerial: "Brownout detector was triggered\n\nrst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)",
|
||||
resumo: "A tensão de alimentação do ESP32 caiu abaixo do limiar operacional seguro (aproximadamente 2.8V ~ 2.43V).",
|
||||
causaRaiz:
|
||||
"Quando o rádio Wi-Fi ou BLE é ligado, o estágio de potência (PA) consome pulsos de corrente muito rápidos que podem superar 500mA em menos de 1 milissegundo. Se a fonte de alimentação, os cabos USB longos/finos, os trilhos de protoboard ou o regulador LDO não fornecerem corrente instantânea com baixa impedância, a tensão no pino 3V3 do chip afunda momentaneamente, disparando o circuito comparador interno de Brownout para evitar corrupção de memória Flash e estados indeterminados.",
|
||||
gambiarra: {
|
||||
titulo: "Desativar o Brownout por software",
|
||||
descricao: "Chamar WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0) para silenciar o erro no código.",
|
||||
consequencia: "Extremamente perigoso: o ESP32 continuará executando instruções sob subtensão, corrompendo a memória Flash SPI, travando registradores e causando comportamento imprevisível em campo sem aviso.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Dimensionamento correto de hardware e desacoplamento",
|
||||
passos: [
|
||||
"Adicione um capacitor de tântalo ou cerâmico de 10µF a 100µF de baixo ESR (Low-ESR) em paralelo com um cerâmico de 100nF o mais próximo possível dos pinos 3V3 e GND do ESP32.",
|
||||
"Utilize reguladores LDO projetados para picos de no mínimo 600mA a 1A com excelente resposta a transitórios (ex: AP2112K, ME6211, TPS73733 ou XC6206 robusto). Evite clones de baixa qualidade do antigo AMS1117.",
|
||||
"Evite alimentar o ESP32 via trilhos compridos de protoboard com cabos jumper finos quando o Wi-Fi estiver transmitindo em potência máxima.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// NÃO desative o Brownout! Se precisar reduzir o pico em testes:
|
||||
#include <WiFi.h>
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
// Opcional: Reduzir ligeiramente a potência máxima de transmissão do Wi-Fi
|
||||
// de 20dBm para 17dBm diminui o pico de corrente em ~20%
|
||||
WiFi.setTxPower(WIFI_POWER_17dBm);
|
||||
WiFi.begin("SSID", "SENHA");
|
||||
}`,
|
||||
codigoEspIdf: `// Configuração no ESP-IDF:
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
void app_main(void) {
|
||||
// No menuconfig: Component config -> ESP32-specific -> Hardware Brownout Reset (Mantenha sempre ATIVO)
|
||||
// Para mitigar picos em ambientes com limite de potência:
|
||||
esp_wifi_set_max_tx_power(68); // 68 = 17dBm (unidades de 0.25dBm)
|
||||
}`,
|
||||
codigoMicroPython: `# Conexão Wi-Fi segura no MicroPython com estabilização:
|
||||
import network
|
||||
import time
|
||||
|
||||
wlan = network.WLAN(network.STA_IF)
|
||||
wlan.active(True)
|
||||
|
||||
# Aguarda estabilização da alimentação antes de iniciar transmissão
|
||||
time.sleep_ms(200)
|
||||
wlan.connect("SSID", "SENHA")
|
||||
|
||||
tentativas = 0
|
||||
while not wlan.isconnected() and tentativas < 30:
|
||||
time.sleep_ms(200)
|
||||
tentativas += 1
|
||||
|
||||
if wlan.isconnected():
|
||||
print("Wi-Fi Conectado! IP:", wlan.ifconfig()[0])
|
||||
else:
|
||||
print("[ERRO] Falha ao conectar Wi-Fi")`,
|
||||
dicaPro: "Se estiver projetando sua própria PCB, coloque um plano de terra sólido sob o módulo e trilhas de alimentação com largura mínima de 0.5mm a 1mm para suportar os surtos de corrente sem queda resistiva (IR drop).",
|
||||
},
|
||||
{
|
||||
id: "strapping-pins",
|
||||
titulo: "Conflito de Strapping Pins no Boot",
|
||||
categoria: "alimentacao",
|
||||
sintomas: ["bootloop", "upload-fail"],
|
||||
gravidade: "Crítica",
|
||||
logSerial: "rst:0x1 (POWERON_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)\nflash read err, 1000\nwaiting for download",
|
||||
resumo: "O ESP32 não inicializa o firmware da Flash ou entra acidentalmente em modo de download porque um pino de strapping foi forçado a um nível lógico incorreto no reset.",
|
||||
causaRaiz:
|
||||
"No momento exato em que o pino EN/CHIP_PU sobe (Power-On Reset), a CPU amostra o estado de pinos específicos (Strapping Pins) para configurar tensão de Flash (1.8V vs 3.3V), modo de boot (Download UART vs SPI Flash) e saída de clock. Se você conectar sensores, relés ou LEDs com pull-up/pull-down nesses pinos, o microcontrolador lerá um nível lógico inválido e travará o boot.",
|
||||
gambiarra: {
|
||||
titulo: "Colocar delays no código ou desconectar na mão toda vez que liga",
|
||||
descricao: "Tentar tratar o problema via software no setup() ou depender de desconectar fios manualmente antes de cada reinicialização.",
|
||||
consequencia: "Inútil: os Strapping Pins são lidos por hardware antes mesmo da CPU carregar qualquer linha do seu código ou do bootloader.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Mapeamento seguro de GPIOs e isolamento no reset",
|
||||
passos: [
|
||||
"ESP32 Clássico: Evite usar GPIO 0 (Boot), GPIO 2 (deve estar LOW ou flutuando no flash), GPIO 12 (define tensão de Flash: se puxado para HIGH no reset, queima/trava a flash de 3.3V) e GPIO 15 (silencia mensagens de log de boot se LOW).",
|
||||
"ESP32-C3: Evite puxar GPIO 8 para LOW ou GPIO 9 para LOW no reset.",
|
||||
"ESP32-S3: Atenção com GPIO 0, GPIO 45 (tensão VDD_SPI) e GPIO 46.",
|
||||
"Se for estritamente necessário usar esses pinos para periféricos, utilize transistores ou buffers para isolá-los até que o sinal EN esteja totalmente estabilizado.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// RECOMENDAÇÃO DE PINAGEM SEGURA (ESP32 Clássico):
|
||||
// Pinos ideais para I2C / SPI / Sensores gerais:
|
||||
// SDA: GPIO 21 | SCL: GPIO 22
|
||||
// SPI: MOSI 23 | MISO 19 | SCK 18 | CS 5
|
||||
|
||||
// ATENÇÃO: GPIOs 34, 35, 36 (VP), 39 (VN) são APENAS ENTRADA (sem pull-up interno).
|
||||
// Nunca tente usá-los como pinMode(..., OUTPUT); nem para I2C/SPI.`,
|
||||
codigoEspIdf: `// No ESP-IDF, proteja a configuração de tensão de Flash via eFuse (CUIDADO: IRREVERSÍVEL):
|
||||
// Se você usa ESP32 clássico e precisa liberar GPIO12, pode queimar o eFuse de 3.3V:
|
||||
// espefuse.py --port /dev/ttyUSB0 set_flash_voltage 3.3V
|
||||
// Isso desativa a amostragem de hardware no GPIO12 para sempre.`,
|
||||
codigoMicroPython: `# Configuração correta de pinos no MicroPython:
|
||||
from machine import Pin
|
||||
|
||||
# ✅ Pinos seguros para saídas e botões com pull-up interno:
|
||||
led = Pin(2, Pin.OUT) # GPIO 2
|
||||
botao = Pin(4, Pin.IN, Pin.PULL_UP) # GPIO 4 (seguro)
|
||||
|
||||
# ⚠️ Pinos 34, 35, 36, 39 são APENAS ENTRADA e não têm pull-up interno:
|
||||
sensor_analogico = Pin(36, Pin.IN) # Correto (requer resistor externo se for botão)`,
|
||||
dicaPro: "Lembre-se sempre: pinos 'Input-Only' (GPI 34 a 39 no ESP32 clássico) não possuem circuitos de pull-up/pull-down de silício nem transistores de saída. Sensores analógicos ou botões neles exigem resistores de pull-up externos.",
|
||||
},
|
||||
{
|
||||
id: "guru-load-prohibited",
|
||||
titulo: "Guru Meditation: LoadProhibited / StoreProhibited",
|
||||
categoria: "cpu-panics",
|
||||
sintomas: ["bootloop", "null-pointer"],
|
||||
gravidade: "Crítica",
|
||||
logSerial: "Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.\nCore 0 register dump:\nPC : 0x400d14bc PS : 0x00060830 A0 : 0x800d1512 A1 : 0x3ffb1f20 \nEXCVADDR: 0x00000000",
|
||||
resumo: "A CPU tentou ler (Load) ou escrever (Store) em um endereço de memória inacessível ou inválido, tipicamente o endereço nulo 0x00000000.",
|
||||
causaRaiz:
|
||||
"Essa é a clássica desreferência de ponteiro nulo (Null Pointer Dereference) ou uso de ponteiro solto (Dangling Pointer). O registrador EXCVADDR indica o endereço que causou a falha: se EXCVADDR for 0x00000000 ou muito próximo de zero (ex: 0x00000008, que é um offset de struct), significa que você tentou acessar membros de um objeto/ponteiro que não foi inicializado ou cujo malloc/criação falhou.",
|
||||
gambiarra: {
|
||||
titulo: "Adicionar delays aleatórios ou reiniciar no loop sem tratar",
|
||||
descricao: "Achar que é problema de temporização e encher o código de delay() ou mascarar o reinício automático sem investigar a causa.",
|
||||
consequencia: "O sistema continuará quebrando aleatoriamente em produção quando a condição de ponteiro nulo se repetir.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Validação defensiva e Decodificação de Backtrace",
|
||||
passos: [
|
||||
"Verifique sempre se retornos de funções de alocação ou busca (malloc, WiFi.client(), JSON parsing, xQueueReceive) não retornaram NULL antes de acessar seus campos.",
|
||||
"Instale o 'Espressif Exception Decoder' na sua IDE (Arduino IDE / PlatformIO) ou use o comando 'xtensa-esp32-elf-addr2line -pfia -e firmware.elf 0x400d14bc' para descobrir exatamente a linha do seu código .c/.cpp onde o crash aconteceu.",
|
||||
"No ESP-IDF, execute 'idf.py monitor' que decodifica o backtrace de pilha automaticamente em tempo real.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// PROGRAMAÇÃO DEFENSIVA:
|
||||
struct SensorData {
|
||||
float temperatura;
|
||||
float umidade;
|
||||
};
|
||||
|
||||
void processarSensor(SensorData* sensor) {
|
||||
// Verificação obrigatória contra LoadProhibited:
|
||||
if (sensor == nullptr) {
|
||||
Serial.println("[ERRO] Ponteiro de sensor nulo!");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.printf("Temp: %.1f C\\n", sensor->temperatura);
|
||||
}`,
|
||||
codigoEspIdf: `// No ESP-IDF, use ESP_ERROR_CHECK ou assertivas explícitas:
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
|
||||
static const char* TAG = "SENSOR";
|
||||
|
||||
esp_err_t ler_dado(char* buffer, size_t max_len) {
|
||||
ESP_RETURN_ON_FALSE(buffer != NULL, ESP_ERR_INVALID_ARG, TAG, "Buffer nulo fornecido!");
|
||||
// Operação segura...
|
||||
return ESP_OK;
|
||||
}`,
|
||||
codigoMicroPython: `# Prevenção contra NoneType e exceções de objeto no MicroPython:
|
||||
import json
|
||||
|
||||
def processar_sensor(dados_raw):
|
||||
# Proteção defensiva contra payload nulo:
|
||||
if dados_raw is None:
|
||||
print("[ERRO] Dados nulos recebidos!")
|
||||
return None
|
||||
|
||||
try:
|
||||
obj = json.loads(dados_raw)
|
||||
# Uso seguro de .get() com valor padrão para evitar KeyError
|
||||
temperatura = obj.get("temp", 0.0)
|
||||
return temperatura
|
||||
except (ValueError, AttributeError) as e:
|
||||
print("Erro ao processar objeto:", e)
|
||||
return None`,
|
||||
dicaPro: "Se EXCVADDR for algo como 0x3fxxxxxx ou 0x40xxxxxx mas seu código falha, você pode estar acessando um array fora do limite (buffer overflow) que sobrescreveu ponteiros na memória.",
|
||||
},
|
||||
{
|
||||
id: "guru-iram-cache",
|
||||
titulo: "Cache Error / InstructionFetchError em ISRs",
|
||||
categoria: "cpu-panics",
|
||||
sintomas: ["bootloop", "null-pointer"],
|
||||
gravidade: "Alta",
|
||||
logSerial: "Guru Meditation Error: Core 0 panic'ed (Cache disabled but cached memory region accessed)\nGuru Meditation Error: Core 0 panic'ed (InstructionFetchError)",
|
||||
resumo: "Uma rotina de interrupção (ISR) tentou executar código ou ler dados da Flash SPI enquanto a Flash estava desativada para uma operação de escrita/leitura.",
|
||||
causaRaiz:
|
||||
"Por padrão, o código do ESP32 fica armazenado na memória Flash externa e é carregado sob demanda para a CPU através da memória Cache interna. Quando o ESP32 grava dados na Flash (como em gravações NVS, LittleFS, SPIFFS ou atualização OTA), o controlador desativa o Cache de instruções temporariamente. Se uma interrupção de hardware (timer, GPIO, etc.) disparar nesse instante e a função ISR estiver na Flash, a CPU não consegue buscar a próxima instrução e entra em pânico imediato.",
|
||||
gambiarra: {
|
||||
titulo: "Desativar interrupções antes de gravar na Flash",
|
||||
descricao: "Tentar envolver operações de gravação de arquivos em blocos de noInterrupts() indiscriminadamente.",
|
||||
consequencia: "Gera perda de pulsos de sensores de alta velocidade, instabilidade nos timers do sistema e potenciais estouros de Watchdog.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Alocar ISRs e constantes em IRAM / DRAM",
|
||||
passos: [
|
||||
"Decore TODA função de callback de interrupção com o atributo IRAM_ATTR (ou IRAM_ATTR static void...).",
|
||||
"Garanta que variáveis ou strings acessadas dentro da ISR também residam em DRAM (evite usar strings literais diretas dentro da ISR sem a tag DRAM_ATTR no ESP-IDF).",
|
||||
"Nunca chame funções pesadas de bibliotecas externas (como Serial.print ou cálculos de float pesados) dentro de uma ISR.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// ISR declarada corretamente na IRAM:
|
||||
volatile uint32_t contadorPulsos = 0;
|
||||
|
||||
void IRAM_ATTR tratarInterrupcaoGPIO() {
|
||||
contadorPulsos++;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
pinMode(4, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(4), tratarInterrupcaoGPIO, FALLING);
|
||||
}`,
|
||||
codigoEspIdf: `// No ESP-IDF:
|
||||
#include "esp_attr.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
static volatile uint32_t pulsos = 0;
|
||||
|
||||
// Função colocada explicitamente na memória interna IRAM:
|
||||
static void IRAM_ATTR gpio_isr_handler(void* arg) {
|
||||
pulsos++;
|
||||
}
|
||||
|
||||
void app_main(void) {
|
||||
gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
|
||||
gpio_isr_handler_add(GPIO_NUM_4, gpio_isr_handler, NULL);
|
||||
}`,
|
||||
codigoMicroPython: `# Tratamento seguro de interrupções (ISR) no MicroPython:
|
||||
import micropython
|
||||
from machine import Pin
|
||||
|
||||
# Aloca buffer de emergência para depurar exceções dentro de ISRs:
|
||||
micropython.alloc_emergency_exception_buf(100)
|
||||
|
||||
contador_pulsos = 0
|
||||
|
||||
# Callback de interrupção: NÃO aloque memória (sem strings, sem floats novos)
|
||||
def tratar_pulso(pin):
|
||||
global contador_pulsos
|
||||
contador_pulsos += 1
|
||||
|
||||
sensor = Pin(4, Pin.IN, Pin.PULL_UP)
|
||||
sensor.irq(trigger=Pin.IRQ_FALLING, handler=tratar_pulso)`,
|
||||
dicaPro: "Se você passar ESP_INTR_FLAG_IRAM ao registrar a interrupção no ESP-IDF, qualquer função chamada por essa interrupção (inclusive funções do FreeRTOS) DEVE suportar IRAM (ex: xQueueSendFromISR).",
|
||||
},
|
||||
{
|
||||
id: "freertos-twdt",
|
||||
titulo: "Task Watchdog Timer (TWDT) Timeout",
|
||||
categoria: "freertos",
|
||||
sintomas: ["bootloop", "wdt-reset"],
|
||||
gravidade: "Crítica",
|
||||
logSerial: "E (10532) task_wdt: Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:\nE (10532) task_wdt: - IDLE0 (CPU 0)\nTask watchdog got triggered. System will be reset.",
|
||||
resumo: "Uma tarefa de alta prioridade entrou em um loop bloqueante e não cedeu tempo de CPU, impedindo que a tarefa IDLE alimente o cão de guarda.",
|
||||
causaRaiz:
|
||||
"O FreeRTOS no ESP32 executa uma tarefa essencial de prioridade 0 chamada IDLE em cada núcleo de CPU. O Task Watchdog monitora se a tarefa IDLE consegue rodar periodicamente (por padrão, a cada 5 segundos). Se você criar uma tarefa com prioridade >= 1 que contenha um loop while(1) sem nenhuma chamada bloqueante (vTaskDelay, leitura de fila, semáforo), a CPU fica 100% ocupada e o Watchdog dispara um reset de emergência.",
|
||||
gambiarra: {
|
||||
titulo: "Desabilitar o Task Watchdog no menuconfig ou aumentar para 60s",
|
||||
descricao: "Desligar o TWDT para o código parar de reiniciar.",
|
||||
consequencia: "Se o seu código travar em um loop infinito ou deadlock, o microcontrolador ficará congelado para sempre, exigindo que alguém vá até o local desligar da tomada.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Arquitetura orientada a eventos e concessão de CPU (Yield)",
|
||||
passos: [
|
||||
"Nunca utilize loops de espera ativa vazios while(!condicao); em tarefas FreeRTOS.",
|
||||
"Sempre insira vTaskDelay(pdMS_TO_TICKS(10)) ou espere por um evento através de xQueueReceive(), ulTaskNotifyTake() ou xSemaphoreTake() com timeout.",
|
||||
"Se for necessário executar um processamento matemático contínuo e pesado, alimente o Watchdog explicitamente com esp_task_wdt_reset().",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// FORMA CORRETA NO ARDUINO COM FREERTOS:
|
||||
void minhaTarefa(void *pvParameters) {
|
||||
for (;;) {
|
||||
// Executa a leitura do sensor
|
||||
float valor = analogRead(36);
|
||||
|
||||
// LIBERA a CPU para o FreeRTOS e a tarefa IDLE:
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); // Aguarda 100ms de forma não-bloqueante
|
||||
}
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF com Task Watchdog:
|
||||
#include "esp_task_wdt.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
void tarefa_processamento(void *pvParameters) {
|
||||
// Opcional: Inscrever a própria tarefa no TWDT
|
||||
esp_task_wdt_add(NULL);
|
||||
|
||||
while (1) {
|
||||
// Processamento...
|
||||
|
||||
// Alimenta o Watchdog se o bloco for longo:
|
||||
esp_task_wdt_reset();
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
}
|
||||
}`,
|
||||
codigoMicroPython: `# Watchdog e laços não-bloqueantes com uasyncio no MicroPython:
|
||||
from machine import WDT
|
||||
import uasyncio as asyncio
|
||||
|
||||
# Inicializa o Watchdog de hardware com timeout de 5 segundos
|
||||
wdt = WDT(timeout=5000)
|
||||
|
||||
async def tarefa_sensor():
|
||||
while True:
|
||||
# Alimenta o cão de guarda a cada ciclo saudável:
|
||||
wdt.feed()
|
||||
|
||||
# Cede controle para o escalonador cooperativo:
|
||||
await asyncio.sleep_ms(100)
|
||||
|
||||
async def main():
|
||||
asyncio.create_task(tarefa_sensor())
|
||||
while True:
|
||||
await asyncio.sleep(1)
|
||||
|
||||
asyncio.run(main())`,
|
||||
dicaPro: "No Arduino, a função delay(ms) na verdade chama internamente o vTaskDelay do FreeRTOS. Porém, loops que usam delayMicroseconds() ou operações puras de CPU não cedem tempo e podem disparar o TWDT se durarem mais de alguns segundos.",
|
||||
},
|
||||
{
|
||||
id: "freertos-stack-overflow",
|
||||
titulo: "Stack Overflow (Estouro de Pilha da Tarefa)",
|
||||
categoria: "freertos",
|
||||
sintomas: ["bootloop", "null-pointer"],
|
||||
gravidade: "Crítica",
|
||||
logSerial: "Guru Meditation Error: Core 1 panic'ed (Unhandled debug exception).\nDebug exception reason: Stack canary watchpoint triggered (minha_tarefa)",
|
||||
resumo: "A tarefa consumiu mais memória de pilha (Stack) do que a quantidade alocada em sua criação, corrompendo o canário de proteção do RTOS.",
|
||||
causaRaiz:
|
||||
"Cada tarefa no FreeRTOS recebe um bloco fixo de memória contígua para suas variáveis locais, argumentos de funções e endereços de retorno de chamadas. Se você declarar arrays grandes (ex: char buffer[2048];), instanciar buffers JSON pesados (ex: DynamicJsonDocument doc(4096);), ou fizer chamadas recursivas profundas dentro de uma tarefa configurada com stack padrão de 2048 bytes, a pilha ultrapassa o limite e sobrescreve áreas críticas do sistema.",
|
||||
gambiarra: {
|
||||
titulo: "Colocar 64KB de stack em todas as tarefas sem critério",
|
||||
descricao: "Alocar stacks gigantescas para não se preocupar com estouro.",
|
||||
consequencia: "A memória interna SRAM do ESP32 (cerca de 320KB úteis) se esgotará rapidamente, causando falhas de inicialização do Wi-Fi e alocação de heap.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Dimensionamento consciente e monitoramento com HighWaterMark",
|
||||
passos: [
|
||||
"Meça o consumo real da pilha usando a função uxTaskGetStackHighWaterMark(). Ela retorna o menor número de bytes/words livres restantes que a pilha teve desde o boot.",
|
||||
"Mova buffers volumosos da pilha para a Heap dinâmica (usando malloc/free temporário) ou declare-os como static fora do escopo da função se forem reutilizados.",
|
||||
"Tarefas que utilizam conexões seguras TLS/HTTPS ou MQTT com SSL exigem no mínimo 6KB a 8KB de stack devido à complexidade das rotinas criptográficas do MbedTLS.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// MONITORANDO O STACK NO ARDUINO:
|
||||
void tarefaSensor(void *pvParameters) {
|
||||
for (;;) {
|
||||
// Código da tarefa...
|
||||
|
||||
// Verifica o espaço livre mínimo da pilha (em Words no FreeRTOS clássico / Bytes no ESP32)
|
||||
UBaseType_t espacoLivre = uxTaskGetStackHighWaterMark(NULL);
|
||||
Serial.printf("[STACK] Espaço livre mínimo: %d bytes\\n", (int)espacoLivre);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
// Aloca 4096 bytes (4KB) de forma equilibrada:
|
||||
xTaskCreatePinnedToCore(tarefaSensor, "tarefaSensor", 4096, NULL, 1, NULL, 1);
|
||||
}`,
|
||||
codigoEspIdf: `// Habilite a checagem dupla de Stack no menuconfig:
|
||||
// Component config -> FreeRTOS -> Set a end of stack check -> Option 2 (Check by Stack Canary)
|
||||
// Isso detecta o estouro ANTES que dados sejam corrompidos em tempo de execução.`,
|
||||
codigoMicroPython: `# Monitoramento de memória e pilha no MicroPython:
|
||||
import gc
|
||||
import micropython
|
||||
|
||||
# Exibe estatísticas de memória RAM e pilha da VM do Python:
|
||||
micropython.mem_info()
|
||||
|
||||
# Executa garbage collector para liberar blocos órfãos:
|
||||
gc.collect()
|
||||
print("Memória Heap Livre:", gc.mem_free(), "bytes")
|
||||
print("Memória Heap Alocada:", gc.mem_alloc(), "bytes")`,
|
||||
dicaPro: "Se a sua função precisa processar um JSON ou pacote HTTP esporadicamente, aloque o buffer no Heap apenas durante o processamento e libere-o logo em seguida, em vez de inflar o Stack permanente da tarefa.",
|
||||
},
|
||||
{
|
||||
id: "memoria-fragmentacao-heap",
|
||||
titulo: "Fragmentação de Heap e Memory Leaks",
|
||||
categoria: "memoria",
|
||||
sintomas: ["random-freeze", "tls-fail"],
|
||||
gravidade: "Alta",
|
||||
logSerial: "E (45892) mbedtls: mbedtls_ssl_setup returned -0x7f00\nE (45892) esp-tls: create_ssl_handle failed\nE (45893) HTTP_CLIENT: Connection failed, out of memory",
|
||||
resumo: "O microcontrolador falha ao alocar memória mesmo reportando uma quantidade total de memória livre aparentemente alta.",
|
||||
causaRaiz:
|
||||
"A memória Heap fica fragmentada quando ocorrem milhares de alocações e desalocações de tamanhos variados ao longo do tempo (muito comum ao usar objetos String do Arduino com concatenação contínua de texto em loops). O heap se divide em pequenos blocos livres separados por blocos ocupados. Quando o driver de Wi-Fi ou a biblioteca TLS precisa de um único bloco contíguo de 40KB para o buffer de criptografia SSL, o malloc falha mesmo que existam 100KB de memória livre total dispersa.",
|
||||
gambiarra: {
|
||||
titulo: "Reiniciar o ESP32 periodicamente com ESP.restart() a cada X horas",
|
||||
descricao: "Agendar um reboot diário para limpar a memória fragmentada.",
|
||||
consequencia: "Apenas camufla o defeito: em condições de pico de requisições o dispositivo cairá muito antes do reboot programado.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Evitar strings dinâmicas e utilizar buffers estáticos pré-alocados",
|
||||
passos: [
|
||||
"No Arduino, evite a classe String. Utilize buffers de caracteres em estilo C (char buffer[128];) com funções seguras como snprintf().",
|
||||
"Monitore a fragmentação acompanhando a relação entre a memória livre total (heap_caps_get_free_size) e o maior bloco contíguo livre (heap_caps_get_largest_free_block).",
|
||||
"Em firmwares complexos no ESP-IDF, ative o Heap Memory Tracing (CONFIG_HEAP_TRACING) para listar exatamente quais arquivos e linhas esqueceram de chamar free().",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// COMPARAÇÃO:
|
||||
// ❌ EVITE (Gera fragmentação severa de Heap):
|
||||
// String json = "{\\"temp\\":";
|
||||
// json += String(temperatura) + "}";
|
||||
|
||||
// ✅ CORRETO (Sem alocação dinâmica no Heap):
|
||||
char payload[64];
|
||||
snprintf(payload, sizeof(payload), "{\\"temp\\":%.2f,\\"umid\\":%.2f}", temperatura, umidade);
|
||||
|
||||
// Monitoramento:
|
||||
Serial.printf("Heap Livre: %u | Maior Bloco: %u\\n",
|
||||
ESP.getFreeHeap(),
|
||||
ESP.getMaxAllocHeap());`,
|
||||
codigoEspIdf: `// Monitoramento de Heap no ESP-IDF:
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
void inspecionar_memoria(void) {
|
||||
size_t livre_total = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
size_t maior_bloco = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
|
||||
|
||||
ESP_LOGI("HEAP", "Total livre: %d bytes | Maior bloco continuo: %d bytes", livre_total, maior_bloco);
|
||||
}`,
|
||||
codigoMicroPython: `# Prevenção de fragmentação de Heap no MicroPython:
|
||||
import gc
|
||||
|
||||
# 1. Habilita coleta automática
|
||||
gc.enable()
|
||||
|
||||
# 2. Pré-aloque bytearrays para reaproveitamento em vez de criar novas strings:
|
||||
buffer_leitura = bytearray(256)
|
||||
|
||||
def ler_sensor_sem_alocacao(stream):
|
||||
# Lê reutilizando o mesmo espaço em memória (Zero-Allocation):
|
||||
bytes_lidos = stream.readinto(buffer_leitura)
|
||||
return buffer_leitura[:bytes_lidos]
|
||||
|
||||
# 3. Dispare o GC antes de abrir conexões pesadas (como HTTPS / TLS):
|
||||
gc.collect()
|
||||
print(f"Heap Livre: {gc.mem_free()} B | Alocado: {gc.mem_alloc()} B")`,
|
||||
dicaPro: "Se o maior bloco contíguo livre for menor que 35KB ~ 40KB, conexões HTTPS/TLS modernas falharão durante o handshake de certificados.",
|
||||
},
|
||||
{
|
||||
id: "memoria-dma-psram",
|
||||
titulo: "Falha de Alocação DMA em Memória Externa (PSRAM)",
|
||||
categoria: "memoria",
|
||||
sintomas: ["bootloop", "random-freeze"],
|
||||
gravidade: "Alta",
|
||||
logSerial: "E (1204) spi_master: spi_bus_initialize: DMA channel not compatible with external RAM buffer\nESP_ERROR_CHECK failed: esp_err_t 0x102 (ESP_ERR_INVALID_ARG)",
|
||||
resumo: "O firmware tentou passar um buffer alocado em PSRAM externa para um periférico com DMA (SPI, I2S, LCD, SDMMC) que só tem acesso à SRAM interna.",
|
||||
causaRaiz:
|
||||
"Nos chips da família ESP32 (especialmente ESP32 clássico, ESP32-S2 e ESP32-S3 com barramento padrão), o controlador de DMA dos periféricos não possui barramento físico com acesso direto à memória PSRAM externa conectada via SPI/QSPI. O DMA exige que os buffers de transmissão e recepção estejam obrigatoriamente localizados na SRAM interna do chip.",
|
||||
gambiarra: {
|
||||
titulo: "Desativar o DMA nos periféricos",
|
||||
descricao: "Configurar o barramento SPI/I2S para operar em modo por polling sem DMA.",
|
||||
consequencia: "A taxa de transferência cai drasticamente e a CPU fica 100% ocupada durante o envio de frames para displays ou streaming de áudio.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Alocação explícita com MALLOC_CAP_DMA e MALLOC_CAP_INTERNAL",
|
||||
passos: [
|
||||
"Sempre aloque buffers dedicados a DMA utilizando a função heap_caps_malloc(tamanho, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL).",
|
||||
"Mantenha dados pesados não-DMA (como imagens decodificadas, modelos de machine learning e áudio em repouso) na PSRAM, e copie blocos menores para buffers de DMA internos sob demanda (ping-pong buffering).",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// Alocando buffer para DMA no Arduino ESP32:
|
||||
#include <esp_heap_caps.h>
|
||||
|
||||
uint8_t* dmaBuffer = nullptr;
|
||||
|
||||
void setup() {
|
||||
size_t tamanho = 4096;
|
||||
// Garante que o buffer reside na SRAM interna compatível com DMA:
|
||||
dmaBuffer = (uint8_t*) heap_caps_malloc(tamanho, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
|
||||
if (dmaBuffer == nullptr) {
|
||||
Serial.println("[ERRO] Falha ao alocar buffer DMA na memória interna!");
|
||||
}
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF:
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
uint8_t* alocar_buffer_spi(size_t len) {
|
||||
return (uint8_t*) heap_caps_aligned_alloc(4, len, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
}`,
|
||||
codigoMicroPython: `# No MicroPython, verifique a memória PSRAM disponível:
|
||||
import gc
|
||||
import esp32
|
||||
|
||||
# Se o firmware foi compilado com suporte a SPIRAM (ex: firmwares com 'SPIRAM'):
|
||||
print("Memória total acessível no MicroPython:", gc.mem_free() + gc.mem_alloc(), "bytes")
|
||||
|
||||
# Para operações rápidas com periféricos, use bytearrays contíguos:
|
||||
buffer_spi = bytearray(1024)`,
|
||||
dicaPro: "No ESP32-P4, a arquitetura avançada de barramento AXI permite DMA em certas regiões externas, mas para toda a linha ESP32/S2/S3/C3 a regra da SRAM interna é estrita.",
|
||||
},
|
||||
{
|
||||
id: "boot-failed-connect",
|
||||
titulo: "Failed to connect to ESP32: Timed out waiting for packet header",
|
||||
categoria: "boot-flash",
|
||||
sintomas: ["upload-fail"],
|
||||
gravidade: "Média",
|
||||
logSerial: "A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header\nesptool.py v4.6\nConnecting...................",
|
||||
resumo: "A ferramenta de gravação (esptool / Arduino IDE / PlatformIO) não conseguiu colocar o microcontrolador no modo de bootloader UART.",
|
||||
causaRaiz:
|
||||
"Para iniciar a gravação do firmware, o chip de conversão USB-Serial (CH340, CP2102, FTDI) utiliza as linhas DTR e RTS para puxar o pino GPIO 0 para LOW enquanto pulsa o pino EN/RST para LOW e depois HIGH. Em muitas placas de desenvolvimento populares, o circuito de temporização RC (resistor-capacitor) do pino EN não possui capacitância suficiente para segurar o reset durante a transição do sinal DTR.",
|
||||
gambiarra: {
|
||||
titulo: "Ficar segurando o botão BOOT com o dedo a cada upload",
|
||||
descricao: "Pressionar o botão físico BOOT/GPIO0 toda vez que o compilador terminar de gerar o binário.",
|
||||
consequencia: "Inconveniente para desenvolvimento ágil e impossível em placas seladas ou embutidas dentro de gabinetes.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Capacitor de 10µF no pino EN ou verificação do cabo de dados",
|
||||
passos: [
|
||||
"Conecte um capacitor eletrolítico ou cerâmico de 10µF (ou 1µF a 10µF) entre o pino EN (RST) e o GND da placa. Isso estabiliza a rampa de reset automático.",
|
||||
"Verifique se o cabo USB possui linhas de dados (D+ e D-) ativas. Muitos cabos de carregador de celular baratos possuem apenas os fios de alimentação VBUS e GND.",
|
||||
"No Linux, certifique-se de que seu usuário pertence ao grupo 'dialout' (sudo usermod -a -G dialout $USER) e que o serviço 'brltty' não está sequestrando a porta serial.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// Dica de Linha de Comando para testar a comunicação serial com o esptool:
|
||||
// python -m esptool --port /dev/ttyUSB0 chip_id
|
||||
// Se retornar o MAC e o modelo do chip, a comunicação física está perfeita.`,
|
||||
codigoEspIdf: `// No ESP-IDF:
|
||||
// idf.py -p /dev/ttyUSB0 -b 460800 flash
|
||||
// Se o upload falhar em altas velocidades, reduza a taxa de baud rate para 115200:
|
||||
// idf.py -p /dev/ttyUSB0 -b 115200 flash`,
|
||||
codigoMicroPython: `# Gravação do firmware MicroPython oficial no ESP32 via terminal:
|
||||
# 1. Apague a memória Flash:
|
||||
# esptool.py --port /dev/ttyUSB0 erase_flash
|
||||
|
||||
# 2. Grave o binário com taxa de baud segura:
|
||||
# esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 ESP32_GENERIC-*.bin`,
|
||||
dicaPro: "Se estiver usando módulos ESP32-S3 ou C3 com USB nativo (Direct USB-JTAG), certifique-se de que a porta correta selecionada é a porta CDC/JTAG e não a UART legada.",
|
||||
},
|
||||
{
|
||||
id: "tls-sntp-clock-fail",
|
||||
titulo: "Falha de Handshake TLS/HTTPS por Relógio Desincronizado",
|
||||
categoria: "conectividade",
|
||||
sintomas: ["tls-fail", "random-freeze"],
|
||||
gravidade: "Alta",
|
||||
logSerial: "E (15420) esp-tls-mbedtls: mbedtls_ssl_handshake returned -0x2700\nE (15420) esp-tls: Failed to verify peer certificate!\nE (15421) esp-tls: Verification info: The certificate is not yet valid (or has expired)",
|
||||
resumo: "Conexões seguras HTTPS, AWS IoT, MQTT com TLS ou APIs Web falham porque o relógio interno do ESP32 está na data padrão de 01/01/1970.",
|
||||
causaRaiz:
|
||||
"Certificados de segurança digitais (X.509 SSL/TLS) possuem um período estrito de validade (Not Before e Not After). Como o ESP32 não possui uma bateria de RTC externa por padrão, ao ligar seu relógio interno sempre inicia na época Unix zero (1970). Quando o cliente MbedTLS valida a data do certificado do servidor, considera que o certificado 'ainda não é válido' (pois 2026 é no futuro em relação a 1970) e aborta a conexão criptografada imediatamente com o erro -0x2700 (MBEDTLS_ERR_X509_CERT_VERIFY_FAILED).",
|
||||
gambiarra: {
|
||||
titulo: "Desativar a validação de certificados SSL (Insecure / No-Verify)",
|
||||
descricao: "Usar client.setInsecure() no Arduino ou desabilitar checagem de CA no ESP-IDF.",
|
||||
consequencia: "Abre brecha gravíssima de segurança: seu dispositivo fica vulnerável a ataques de Man-in-the-Middle (MitM), permitindo que invasores interceptem senhas e firmwares.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Sincronização obrigatória de data e hora via SNTP antes de conexões TLS",
|
||||
passos: [
|
||||
"Logo após obter IP no Wi-Fi, inicie o cliente SNTP apontando para servidores confiáveis (ex: pool.ntp.br, time.google.com).",
|
||||
"Aguarde o status do relógio atingir o estado sincronizado antes de iniciar a primeira conexão HTTPS/MQTT.",
|
||||
"Configure o fuso horário (Timezone) correto para formatar logs com horários precisos.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// SINCRONIZAÇÃO SNTP ANTES DO HTTPS NO ARDUINO:
|
||||
#include <WiFi.h>
|
||||
#include <time.h>
|
||||
|
||||
void sincronizarRelogio() {
|
||||
// Configura servidores NTP (NTP Brasil e Google)
|
||||
configTime(-3 * 3600, 0, "a.st1.ntp.br", "time.google.com");
|
||||
|
||||
Serial.print("Aguardando sincronizacao de horario");
|
||||
time_t now = time(nullptr);
|
||||
// Ano 2020 em Unix time é 1577836800. Se for menor, ainda está em 1970:
|
||||
while (now < 1577836800) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
now = time(nullptr);
|
||||
}
|
||||
Serial.println("\\n[OK] Horario sincronizado! Conexoes TLS liberadas.");
|
||||
}`,
|
||||
codigoEspIdf: `// SNTP no ESP-IDF:
|
||||
#include "esp_sntp.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
void inicializar_sntp(void) {
|
||||
ESP_LOGI("SNTP", "Iniciando cliente SNTP...");
|
||||
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||||
esp_sntp_setservername(0, "pool.ntp.br");
|
||||
esp_sntp_init();
|
||||
|
||||
// Aguarda sincronização do relógio...
|
||||
}`,
|
||||
codigoMicroPython: `# Sincronização SNTP e requisições HTTPS no MicroPython:
|
||||
import ntptime
|
||||
import time
|
||||
import urequests
|
||||
|
||||
def sincronizar_e_requisitar():
|
||||
try:
|
||||
print("Sincronizando relógio via NTP...")
|
||||
ntptime.host = "pool.ntp.br"
|
||||
ntptime.settime() # Atualiza o RTC interno do ESP32 via NTP
|
||||
print("Hora sincronizada UTC:", time.localtime())
|
||||
|
||||
# Agora o handshake TLS validará o certificado sem o erro -0x2700:
|
||||
resposta = urequests.get("https://api.github.com")
|
||||
print("Resposta HTTPS:", resposta.status_code)
|
||||
resposta.close()
|
||||
except Exception as e:
|
||||
print("[ERRO TLS/NTP]:", e)`,
|
||||
dicaPro: "Se seu projeto opera em ambientes sem acesso à internet externa (rede local isolada), configure um servidor NTP local no roteador ou adicione um módulo RTC físico como o DS3231 via I2C.",
|
||||
},
|
||||
];
|
||||
|
||||
export const regrasDecodificadorLog = [
|
||||
{
|
||||
padrao: /Brownout detector was triggered/i,
|
||||
titulo: "Brownout Detector (Subtensão Crítica)",
|
||||
tipo: "Alimentação / Hardware",
|
||||
explicacao:
|
||||
"A tensão no pino 3V3 do ESP32 caiu abaixo do nível seguro (geralmente por pico de corrente do rádio Wi-Fi/BLE ou fonte subdimensionada).",
|
||||
acaoRecomendada:
|
||||
"Adicione capacitor de 10µF a 100µF Low-ESR no VCC, use fonte estável e verifique o regulador LDO.",
|
||||
},
|
||||
{
|
||||
padrao: /LoadProhibited|StoreProhibited/i,
|
||||
titulo: "Guru Meditation: Load/StoreProhibited (Ponteiro Nulo ou Inválido)",
|
||||
tipo: "CPU Panic / Exceção",
|
||||
explicacao:
|
||||
"Tentativa de ler ou gravar em um endereço inválido na memória (quase sempre desreferência de ponteiro NULL ou array fora de limite).",
|
||||
acaoRecomendada:
|
||||
"Decodifique o Backtrace com o Exception Decoder ou 'addr2line' para identificar a linha exata. Adicione checagens defensivas `if (ptr != NULL)`.",
|
||||
},
|
||||
{
|
||||
padrao: /Cache disabled but cached memory region accessed|InstructionFetchError/i,
|
||||
titulo: "Cache Error em Interrupção (ISR fora da IRAM)",
|
||||
tipo: "CPU Panic / Flash",
|
||||
explicacao:
|
||||
"Uma rotina de interrupção (ISR) tentou rodar a partir da memória Flash enquanto ela estava ocupada gravando dados (NVS, LittleFS ou OTA).",
|
||||
acaoRecomendada:
|
||||
"Adicione o atributo `IRAM_ATTR` na função de interrupção e garanta que ela não acesse variáveis na Flash sem DRAM_ATTR.",
|
||||
},
|
||||
{
|
||||
padrao: /Task watchdog got triggered/i,
|
||||
titulo: "Task Watchdog Timer (TWDT) Timeout",
|
||||
tipo: "FreeRTOS / Multitarefa",
|
||||
explicacao:
|
||||
"Uma tarefa de prioridade alta monopolizou a CPU sem ceder tempo (sem vTaskDelay ou bloqueio), impedindo o watchdog da tarefa IDLE.",
|
||||
acaoRecomendada:
|
||||
"Adicione `vTaskDelay(pdMS_TO_TICKS(10))` em loops longos ou use filas/semáforos em vez de loops `while(1)` contínuos.",
|
||||
},
|
||||
{
|
||||
padrao: /Stack canary watchpoint triggered/i,
|
||||
titulo: "Stack Overflow (Estouro de Pilha da Tarefa)",
|
||||
tipo: "FreeRTOS / Memória",
|
||||
explicacao:
|
||||
"A tarefa excedeu a quantidade de memória de pilha (Stack) alocada na sua criação, corrompendo o canário de proteção.",
|
||||
acaoRecomendada:
|
||||
"Aumente o tamanho da pilha no `xTaskCreate` (ex: de 2048 para 4096 bytes) e mova arrays grandes para o Heap ou variáveis estáticas.",
|
||||
},
|
||||
{
|
||||
padrao: /Timed out waiting for packet header|Failed to connect to ESP32/i,
|
||||
titulo: "Falha de Conexão UART / Upload",
|
||||
tipo: "Bootloader / Conexão",
|
||||
explicacao:
|
||||
"O computador não conseguiu colocar o ESP32 em modo de gravação via DTR/RTS ou o cabo USB não possui linhas de dados.",
|
||||
acaoRecomendada:
|
||||
"Coloque um capacitor de 10µF entre o pino EN e o GND, troque o cabo USB por um com fios de dados e teste segurar o botão BOOT durante a conexão.",
|
||||
},
|
||||
{
|
||||
padrao: /The certificate is not yet valid|-0x2700/i,
|
||||
titulo: "Falha de Certificado SSL/TLS (Relógio em 1970)",
|
||||
tipo: "Conectividade / TLS",
|
||||
explicacao:
|
||||
"O ESP32 tentou autenticar um certificado HTTPS/TLS com a data zerada na época Unix (01/01/1970).",
|
||||
acaoRecomendada:
|
||||
"Sincronize o horário via SNTP (`configTime` no Arduino ou `ntptime.settime()` no MicroPython) antes de iniciar requisições HTTPS seguras.",
|
||||
},
|
||||
{
|
||||
padrao: /rst:0x1 \(POWERON_RESET\),boot:0x[0-9a-fA-F]+/i,
|
||||
titulo: "Reset por Power-On / Strapping Pins",
|
||||
tipo: "Hardware / Boot",
|
||||
explicacao:
|
||||
"O microcontrolador reiniciou e reportou o registrador de strapping pins. Se travar após isso, um pino de boot pode estar em nível lógico incorreto.",
|
||||
acaoRecomendada:
|
||||
"Verifique se GPIOs como 0, 2, 12, 15 (ESP32) ou 8, 9 (C3) estão conectados a resistores ou periféricos que forçam níveis inadequados no boot.",
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,408 @@
|
||||
/**
|
||||
* Base de dados estruturada e abrangente de termos técnicos do Glossário ESP32.
|
||||
* Abrange todas as séries de chips da Espressif (ESP32, S2, S3, S31, C2, C3, C5, C6, C61, H2, H4, P4)
|
||||
* e seus recursos de hardware, periféricos, rádio, segurança e software.
|
||||
*/
|
||||
|
||||
export const categoriasGlossario = [
|
||||
{
|
||||
id: "processamento",
|
||||
nome: "Processamento, CPU & Silício",
|
||||
icone: "Cpu",
|
||||
emoji: "🧠",
|
||||
cor: "blue",
|
||||
descricao: "Arquiteturas Xtensa e RISC-V, núcleos, coprocessadores ULP, aceleradores vetoriais de IA e unidades de ponto flutuante.",
|
||||
termos: [
|
||||
{
|
||||
termo: "Arquitetura Xtensa vs RISC-V",
|
||||
definicao: "Conjunto de instruções base do processador. O ESP32 clássico, S2 e S3 usam núcleos proprietários Tensilica Xtensa (LX6/LX7). As séries modernas C (C2, C3, C5, C6, C61), H (H2, H4) e P (P4) adotam a arquitetura aberta, modular e eficiente RISC-V (32-bit).",
|
||||
exemplo: "ESP32-S3 usa Xtensa LX7 dual-core, enquanto ESP32-C6 usa RISC-V single-core e ESP32-P4 usa RISC-V dual-core a 400 MHz.",
|
||||
},
|
||||
{
|
||||
termo: "Núcleos de CPU (Dual-Core vs Single-Core)",
|
||||
definicao: "Unidades centrais de processamento independentes. Chips dual-core permitem dedicar um núcleo (Core 0) exclusivamente ao rádio Wi-Fi/Bluetooth e escalonamento do FreeRTOS, deixando o segundo núcleo (Core 1) 100% livre para a aplicação e cálculos do usuário.",
|
||||
exemplo: "ESP32, ESP32-S3 e ESP32-P4 são dual-core; ESP32-S2, C2, C3, C6 e H2 são single-core.",
|
||||
},
|
||||
{
|
||||
termo: "Frequência de Clock (MHz)",
|
||||
definicao: "Velocidade de processamento medida em Megahertz (MHz). O ESP-IDF ajusta dinamicamente a frequência (Dynamic Frequency Scaling - DFS) para economizar energia em momentos ociosos.",
|
||||
exemplo: "O ESP32-C2 opera a até 120 MHz; ESP32, S2, S3 e C6 chegam a 160/240 MHz; e o ESP32-P4 atinge 400 MHz.",
|
||||
},
|
||||
{
|
||||
termo: "ULP (Ultra Low Power Coprocessor)",
|
||||
definicao: "Processador secundário independente de consumo ultra baixo que continua rodando instruções, lendo sensores analógicos (ADC), I2C e pinos GPIO enquanto os núcleos principais permanecem desligados em Deep Sleep.",
|
||||
exemplo: "O ESP32 original tem ULP FSM; ESP32-S2, S3 e C6 possuem ULP RISC-V programável em C; ESP32-P4 possui ULP de baixa potência dedicado.",
|
||||
},
|
||||
{
|
||||
termo: "Extensões Vetoriais de IA (Vector Extension / ESP-NN)",
|
||||
definicao: "Instruções especializadas de silício que executam operações matemáticas vetoriais e matriciais com inteiros (int8/int16) em paralelo, acelerando redes neurais convolucionais (CNNs) e processamento de sinal.",
|
||||
exemplo: "ESP32-S3 e ESP32-P4 aceleram inferências de reconhecimento facial, detecção de voz e modelos TensorFlow Lite for Microcontrollers.",
|
||||
},
|
||||
{
|
||||
termo: "FPU (Floating Point Unit)",
|
||||
definicao: "Unidade de processamento de ponto flutuante por hardware que realiza somas, multiplicações e divisões com números decimais (`float`) em um único ciclo de clock, sem sobrecarga de software.",
|
||||
exemplo: "Presente nos núcleos Xtensa do ESP32 e ESP32-S3, e nos núcleos RISC-V de alto desempenho do ESP32-P4.",
|
||||
},
|
||||
{
|
||||
termo: "PPA (Pixel Processing Accelerator)",
|
||||
definicao: "Acelerador gráfico 2D por hardware exclusivo do ESP32-P4 para manipulação acelerada de imagens: rotação de frames, redimensionamento (scaling), mistura de canais alfa (alpha blending) e conversão de cores (RGB565, ARGB8888, YUV420).",
|
||||
exemplo: "Renderização de interfaces gráficas complexas (LVGL) a 60 FPS sem ocupar tempo dos núcleos de CPU principais.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "seguranca",
|
||||
nome: "Segurança, Criptografia & eFuses",
|
||||
icone: "ShieldCheck",
|
||||
emoji: "🔒",
|
||||
cor: "red",
|
||||
descricao: "eFuses invioláveis, Secure Boot V2, Criptografia de Flash XTS-AES, Key Manager, ECC e proteção contra DPA.",
|
||||
termos: [
|
||||
{
|
||||
termo: "eFuse (Electronic Fuses)",
|
||||
definicao: "Conjunto de fusíveis microscópicos de silício de gravação única e irreversível (One-Time Programmable - OTP). Armazenam chaves secretas de criptografia, o endereço MAC de fábrica e bloqueiam interfaces de debug em produtos comerciais.",
|
||||
exemplo: "Usado com a ferramenta `espefuse.py` para gravar chaves de Secure Boot e desativar portas JTAG antes do envio ao consumidor.",
|
||||
},
|
||||
{
|
||||
termo: "Secure Boot (V1 e V2)",
|
||||
definicao: "Protocolo de inicialização segura em que o código da ROM verifica criptograficamente a assinatura RSA-3072 ou ECDSA do bootloader e firmware antes de permitir sua execução, impedindo injeção de código adulterado.",
|
||||
exemplo: "ESP32 clássico usa Secure Boot V1; do ESP32-S2 em diante todos adotam o Secure Boot V2 com múltiplas chaves de assinatura.",
|
||||
},
|
||||
{
|
||||
termo: "Criptografia de Flash (Flash Encryption)",
|
||||
definicao: "Mecanismo de hardware que cifra e decifra em tempo real o conteúdo da memória Flash SPI externa usando o algoritmo XTS-AES. Impede a leitura física do firmware caso a placa seja roubada ou a memória dessoldada.",
|
||||
exemplo: "XTS-AES-128 na maioria dos chips; ESP32-S3, C5, P4 e H4 também suportam XTS-AES-256.",
|
||||
},
|
||||
{
|
||||
termo: "Key Manager",
|
||||
definicao: "Módulo de segurança avançado que provisiona, armazena e opera chaves criptográficas em silício sem nunca expô-las à memória SRAM ou ao firmware, impedindo extração de chaves mesmo sob vulnerabilidades de software.",
|
||||
exemplo: "Presente nas séries de alta segurança como ESP32-S31, ESP32-C5 e ESP32-P4.",
|
||||
},
|
||||
{
|
||||
termo: "ECC & ECDSA em Hardware",
|
||||
definicao: "Aceleradores de curvas elípticas (como P-256 e P-384) e algoritmos de assinatura digital ECDSA em silício, fundamentais para conexão rápida e segura com a nuvem e requisitos de atestação do padrão Matter.",
|
||||
exemplo: "ESP32-S31, C5, C61, P4, H2 e H4 possuem acelerador de hardware para ECDSA.",
|
||||
},
|
||||
{
|
||||
termo: "HMAC & Assinatura Digital (DS)",
|
||||
definicao: "Periféricos de autenticação criptográfica que calculam códigos HMAC e assinam mensagens com chaves secretas gravadas em eFuses de forma invisível para o firmware.",
|
||||
exemplo: "Permite autenticação segura e rápida com AWS IoT Core e Microsoft Azure IoT sem armazenar certificados em texto plano.",
|
||||
},
|
||||
{
|
||||
termo: "TRNG (True Random Number Generator)",
|
||||
definicao: "Gerador de números aleatórios verdadeiros baseado no ruído térmico analógico dos circuitos de rádio e silício, essencial para geração de chaves de sessão em handshakes TLS/HTTPS.",
|
||||
exemplo: "Disponível em todas as séries do ESP32 para garantir entropia segura em conexões HTTPS/MbedTLS.",
|
||||
},
|
||||
{
|
||||
termo: "Proteção contra DPA (Differential Power Analysis)",
|
||||
definicao: "Mecanismo físico de hardware que adiciona ruído e balanceamento no consumo de corrente elétrica do chip para impedir que invasores descubram chaves criptográficas medindo o consumo com osciloscópios.",
|
||||
exemplo: "Presente nas séries ESP32-C5, C6, C61 e H2.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "memoria",
|
||||
nome: "Memória, Barramentos & Armazenamento",
|
||||
icone: "Database",
|
||||
emoji: "💾",
|
||||
cor: "purple",
|
||||
descricao: "SRAM interna, ROM de boot, memórias Flash SPI, PSRAM QSPI/Octal, RTC Memory e alocações de DMA.",
|
||||
termos: [
|
||||
{
|
||||
termo: "SRAM Interna",
|
||||
definicao: "Memória volátil ultrarrápida integrada diretamente no silício da CPU. Utilizada para variáveis do programa, estruturas do FreeRTOS, buffers de drivers e pilha de execução. Perde os dados ao desligar a alimentação.",
|
||||
exemplo: "O ESP32 clássico possui 520 KB de SRAM; ESP32-S3 tem 512 KB; ESP32-C3 tem 400 KB; ESP32-C6 tem 512 KB; ESP32-P4 tem 768 KB.",
|
||||
},
|
||||
{
|
||||
termo: "ROM de Boot",
|
||||
definicao: "Memória somente-leitura gravada permanentemente na fábrica da Espressif contendo o First-Stage Bootloader, tabelas matemáticas e rotinas básicas de inicialização que nunca podem ser alteradas.",
|
||||
exemplo: "Ao ligar, a ROM executa primeiro, verifica os Strapping Pins e carrega o bootloader do usuário da Flash.",
|
||||
},
|
||||
{
|
||||
termo: "Flash SPI (Quad-SPI vs Octal-SPI)",
|
||||
definicao: "Memória não-volátil externa onde reside o firmware da aplicação. Conectada via 4 vias (Quad SPI / QSPI) ou 8 vias de dados (Octal SPI / OPI / OSPI) com o dobro de largura de banda e taxas de transferência.",
|
||||
exemplo: "ESP32-S3 e ESP32-P4 suportam memórias Flash e PSRAM em modo Octal SPI de até 120 MHz para máxima velocidade de carregamento de texturas e código.",
|
||||
},
|
||||
{
|
||||
termo: "PSRAM (Pseudo-Static RAM Externa)",
|
||||
definicao: "Memória RAM externa de alta densidade conectada via SPI/QSPI/OPI que estende a memória do microcontrolador em até dezenas de Megabytes para aplicações que demandam buffers gigantescos.",
|
||||
exemplo: "ESP32-WROVER e ESP32-S3-WROOM-1 com 8 MB de PSRAM externa para decodificação JPEG de câmeras e buffers gráficos de displays TFT.",
|
||||
},
|
||||
{
|
||||
termo: "RTC Fast & Slow SRAM",
|
||||
definicao: "Blocos de memória SRAM dedicados ao domínio de energia do Real-Time Clock (RTC). Permanecem alimentados durante o modo Deep Sleep para armazenar código do ULP e variáveis marcadas com `RTC_DATA_ATTR`.",
|
||||
exemplo: "Manter contadores de leituras ou dados de calibração intactos enquanto o ESP32 dorme em Deep Sleep consumindo 10 µA.",
|
||||
},
|
||||
{
|
||||
termo: "Alocação DMA (MALLOC_CAP_DMA)",
|
||||
definicao: "Memória compatível com Direct Memory Access (DMA), permitindo que periféricos (SPI, I2S, LCD, SDMMC) transfiram dados diretamente para a RAM sem consumir tempo da CPU.",
|
||||
exemplo: "Na maioria dos chips ESP32, o DMA exige alocação exclusiva na SRAM interna através da flag `MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL`.",
|
||||
},
|
||||
{
|
||||
termo: "Fragmentação de Heap",
|
||||
definicao: "Fenômeno em que a memória dinâmica fica dividida em blocos pequenos dispersos após múltiplas alocações e desalocações (muito comum ao usar objetos `String` do Arduino), impedindo alocações contíguas grandes para TLS/Wi-Fi.",
|
||||
exemplo: "Monitorado no ESP-IDF através de `heap_caps_get_largest_free_block()` para prevenir falhas de conexão HTTPS.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "conectividade",
|
||||
nome: "Conectividade Sem Fio & Protocolos",
|
||||
icone: "Wifi",
|
||||
emoji: "📡",
|
||||
cor: "emerald",
|
||||
descricao: "Wi-Fi 4/6, Dual-Band 5 GHz, OFDMA, TWT, Bluetooth Classic, BLE 5.x, LE Audio, Zigbee 3.0, Thread e Matter.",
|
||||
termos: [
|
||||
{
|
||||
termo: "Wi-Fi 6 (802.11ax)",
|
||||
definicao: "Padrão moderno de rede sem fio que traz suporte a OFDMA (comunicação paralela com menor latência), modulação 1024-QAM e o recurso TWT (Target Wake Time) para economizar drasticamente a bateria de sensores IoT.",
|
||||
exemplo: "Presente no ESP32-C6, ESP32-C61 e ESP32-C5.",
|
||||
},
|
||||
{
|
||||
termo: "Wi-Fi Dual-Band (2.4 GHz e 5 GHz)",
|
||||
definicao: "Capacidade de operar tanto na faixa tradicional de 2.4 GHz quanto na faixa de 5 GHz com menor congestionamento eletromagnético, canais de 20 MHz / 40 MHz e maior estabilidade de conexão.",
|
||||
exemplo: "O ESP32-C5 é o primeiro chip da Espressif com rádio Wi-Fi 6 Dual-Band integrado.",
|
||||
},
|
||||
{
|
||||
termo: "OFDMA (Orthogonal Frequency Division Multiple Access)",
|
||||
definicao: "Tecnologia do Wi-Fi 6 que divide um único canal de rádio em dezenas de subportadoras menores (Resource Units), permitindo que o roteador atenda múltiplos dispositivos ESP32 simultaneamente sem colisões.",
|
||||
exemplo: "Reduz a latência de resposta em ambientes residenciais ou industriais densos com dezenas de nós conectados.",
|
||||
},
|
||||
{
|
||||
termo: "TWT (Target Wake Time)",
|
||||
definicao: "Protocolo do Wi-Fi 6 onde o ESP32 e o roteador combinam horários exatos para troca de pacotes, permitindo que o microcontrolador mantenha seu rádio totalmente desligado por longos períodos sem se desconectar da rede.",
|
||||
exemplo: "Sensores alimentados por bateria com ESP32-C6 operando por anos conectados ao Wi-Fi 6 sem perder sincronismo.",
|
||||
},
|
||||
{
|
||||
termo: "Bluetooth Classic (BR/EDR)",
|
||||
definicao: "Protocolo Bluetooth tradicional para transmissão contínua de áudio estéreo (A2DP), portas seriais virtuais (SPP) e dispositivos que exigem alta taxa de transferência sustentada.",
|
||||
exemplo: "Implementação de caixas de som Bluetooth, receptores de áudio e teclados HID no ESP32 clássico.",
|
||||
},
|
||||
{
|
||||
termo: "Bluetooth Low Energy (BLE 5.0 a 5.4)",
|
||||
definicao: "Versão de baixo consumo elétrico do Bluetooth com suporte a taxas de 2 Mbps (2M PHY), longo alcance de centenas de metros (Coded PHY / Long Range), extensões de publicidade e redes mesh Bluetooth.",
|
||||
exemplo: "ESP32-S3 suporta BLE 5.0; ESP32-C6 e ESP32-H2 suportam Bluetooth 5.4 LE.",
|
||||
},
|
||||
{
|
||||
termo: "Bluetooth LE Audio & Auracast",
|
||||
definicao: "Nova geração de áudio Bluetooth de alta fidelidade e baixíssimo consumo com o codec LC3 e suporte a transmissões de áudio para múltiplos ouvintes simultâneos (Broadcast Audio / Auracast).",
|
||||
exemplo: "Disponível na série ESP32-H4 para novos ecossistemas de áudio e fones inteligentes.",
|
||||
},
|
||||
{
|
||||
termo: "IEEE 802.15.4 (Zigbee 3.0 & Thread)",
|
||||
definicao: "Padrão de rádio em 2.4 GHz de baixo consumo e baixa taxa de dados que forma a base física das redes em malha (Mesh) industriais e residenciais Zigbee 3.0 e Thread 1.3.",
|
||||
exemplo: "ESP32-C6, ESP32-H2 e ESP32-H4 possuem transceptor IEEE 802.15.4 integrado no silício.",
|
||||
},
|
||||
{
|
||||
termo: "Matter Protocol",
|
||||
definicao: "Padrão universal e aberto de conectividade para automação residencial mantido pela CSA, funcionando sobre redes Wi-Fi, Ethernet e Thread, compatível nativamente com Apple Home, Google Home, Alexa e Home Assistant.",
|
||||
exemplo: "Lâmpadas e tomadas inteligentes desenvolvidas com ESP-Matter no ESP32-C6 ou ESP32-H2 sem depender de nuvens proprietárias.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "perifericos",
|
||||
nome: "Entradas, Saídas & Periféricos",
|
||||
icone: "Sliders",
|
||||
emoji: "🔌",
|
||||
cor: "amber",
|
||||
descricao: "Pinos GPIO, strapping pins, conversores ADC/DAC, PWM/LEDC, MCPWM, RMT, PCNT, TWAI®/CAN, I2C, SPI e I2S.",
|
||||
termos: [
|
||||
{
|
||||
termo: "GPIO (General Purpose Input/Output)",
|
||||
definicao: "Pinos multifuncionais configuráveis como entradas ou saídas digitais, com resistores de pull-up/pull-down internos selecionáveis e suporte a interrupções externas em qualquer pino.",
|
||||
exemplo: "Leitura de botões, chaveamento de relés e controle de LEDs com `gpio_set_level()` ou `digitalWrite()`.",
|
||||
},
|
||||
{
|
||||
termo: "Strapping Pins",
|
||||
definicao: "Pinos GPIO específicos amostrados por hardware no milissegundo em que o chip sai do reset para determinar o modo de boot (Download UART vs SPI Flash) e níveis de tensão.",
|
||||
exemplo: "GPIO 0 no ESP32 clássico/S3 ou GPIO 9 no ESP32-C3: se puxados para LOW durante o reset, colocam o chip em modo de gravação de firmware.",
|
||||
},
|
||||
{
|
||||
termo: "ADC (Analog-to-Digital Converter)",
|
||||
definicao: "Conversor que transforma níveis contínuos de tensão analógica (0 a 3.3V) em valores numéricos digitais de 12 bits (o ESP32-S2 entrega 13 bits, com 12 efetivos) através de atenuadores configuráveis (0dB, 2.5dB, 6dB, 11dB/12dB).",
|
||||
exemplo: "Leitura de sensores LDR, potenciômetros, termistores e medição do nível de carga de baterias de lítio.",
|
||||
},
|
||||
{
|
||||
termo: "DAC (Digital-to-Analog Converter)",
|
||||
definicao: "Conversor que gera tensões analógicas contínuas proporcionais a valores digitais gerados por software sem necessidade de circuitos externos.",
|
||||
exemplo: "Disponível no ESP32 clássico e ESP32-S2 para sintetizar áudio analógico ou sinais de controle direto.",
|
||||
},
|
||||
{
|
||||
termo: "LEDC (LED PWM Controller)",
|
||||
definicao: "Periférico dedicado a gerar múltiplos canais de modulação por largura de pulso (PWM) com controle de frequência, resolução de até 14-20 bits e transições graduais (fade por hardware) sem ocupar a CPU.",
|
||||
exemplo: "Controle suave de brilho de fitas de LED RGBW e posicionamento de servomotores.",
|
||||
},
|
||||
{
|
||||
termo: "MCPWM (Motor Control PWM)",
|
||||
definicao: "Controlador PWM avançado projetado para acionamento de motores elétricos, inversores de frequência trifásicos, pontes H com tempo morto (dead-time) configurável e captura de encoders em quadratura.",
|
||||
exemplo: "Controle preciso de motores sem escovas (BLDC) e robôs móveis no ESP32 clássico, S3 e P4.",
|
||||
},
|
||||
{
|
||||
termo: "RMT (Remote Control Peripheral)",
|
||||
definicao: "Transceptor e gerador de pulsos de temporização precisa em microssegundos projetado originalmente para controles remotos infravermelhos (NEC, RC5, Sony) e amplamente usado para controlar fitas de LED digitais WS2812B / NeoPixel.",
|
||||
exemplo: "Atualização de centenas de LEDs NeoPixel sem desativar interrupções do sistema.",
|
||||
},
|
||||
{
|
||||
termo: "PCNT (Pulse Counter)",
|
||||
definicao: "Contador de pulsos de hardware que mede a contagem de bordas de subida/descida de sinais externos em alta frequência sem gerar interrupções por software para a CPU.",
|
||||
exemplo: "Leitura de encoders rotativos industriais, tacômetros de velocidade e medidores de vazão de água.",
|
||||
},
|
||||
{
|
||||
termo: "TWAI® (Two-Wire Automotive Interface / CAN Bus)",
|
||||
definicao: "Controlador de barramento veicular e industrial CAN 2.0B compatível com a norma ISO 11898-1 integrado no silício, necessitando apenas de um transceptor físico externo (como SN65HVD230).",
|
||||
exemplo: "Diagnóstico automotivo OBD-II, telemetria de veículos elétricos e automação industrial robusta.",
|
||||
},
|
||||
{
|
||||
termo: "Touch Capacitivo",
|
||||
definicao: "Pinos especializados que medem a variação da capacitância eletrostática quando um dedo se aproxima, permitindo criar botões e sliders sensíveis ao toque através de vidro ou acrílico.",
|
||||
exemplo: "Painéis de comando touch modernos com até 14 canais no ESP32-S2 e S3.",
|
||||
},
|
||||
{
|
||||
termo: "PARLIO (Parallel IO Controller)",
|
||||
definicao: "Barramento paralelo configurável de alta velocidade presente nas séries mais novas (C6, H2, P4) para transferir dados síncronos com clock customizado para displays LCD, câmeras e sensores externos.",
|
||||
exemplo: "Comunicação paralela eficiente com chips periféricos sem recorrer a bit-banging na CPU.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "multimidia",
|
||||
nome: "Multimídia, USB & Interfaces Avançadas",
|
||||
icone: "Sparkles",
|
||||
emoji: "✨",
|
||||
cor: "pink",
|
||||
descricao: "USB OTG nativo, USB Serial/JTAG, USB High-Speed 480Mbps, MIPI CSI/DSI, codificador H.264 e Ethernet MAC.",
|
||||
termos: [
|
||||
{
|
||||
termo: "USB OTG (On-The-Go) Nativo",
|
||||
definicao: "Controlador USB Full-Speed (12 Mbps) embutido no chip que permite ao ESP32 operar como dispositivo periférico (teclado HID, mouse, pendrive Mass Storage) ou como USB Host (lendo pen drives ou periféricos).",
|
||||
exemplo: "Nativamente disponível no ESP32-S2 e ESP32-S3 para criação de teclados customizados e emuladores.",
|
||||
},
|
||||
{
|
||||
termo: "USB Serial/JTAG Nativo",
|
||||
definicao: "Interface USB integrada no silício que fornece simultaneamente uma porta serial de comunicação para o console e uma sonda de depuração JTAG completa sem a necessidade de chips conversores externos (CH340/CP2102).",
|
||||
exemplo: "Permite gravar firmware e debugar com breakpoints no VS Code no ESP32-C3, S3, C6 e H2 apenas com o cabo USB conectado aos pinos D+/D-.",
|
||||
},
|
||||
{
|
||||
termo: "USB 2.0 High-Speed (480 Mbps)",
|
||||
definicao: "Controlador USB 2.0 de alta velocidade capaz de transferir até 480 Mbps com PHY integrado, proporcionando largura de banda 40x superior ao USB Full-Speed.",
|
||||
exemplo: "Exclusivo do ESP32-P4 para streaming de vídeo em alta definição e transferência em massa de dados.",
|
||||
},
|
||||
{
|
||||
termo: "MIPI CSI & MIPI DSI",
|
||||
definicao: "Interfaces seriais diferenciais de alta velocidade padrão da indústria de smartphones: MIPI-CSI (Camera Serial Interface) para sensores de câmera de alta resolução e MIPI-DSI (Display Serial Interface) para telas sensíveis ao toque.",
|
||||
exemplo: "Conexão de telas de 1080p e câmeras de alta taxa de quadros no SoC ESP32-P4.",
|
||||
},
|
||||
{
|
||||
termo: "Codificador de Vídeo H.264 por Hardware",
|
||||
definicao: "Bloco acelerador dedicado que comprime fluxos de vídeo brutos de câmeras no formato padrão H.264 (AVC) em tempo real em resoluções de até 1080p a 30 FPS sem sobrecarregar a CPU.",
|
||||
exemplo: "Câmeras de segurança inteligentes e porteiros eletrônicos com compressão eficiente no ESP32-P4.",
|
||||
},
|
||||
{
|
||||
termo: "Ethernet MAC 10/100 Mbps",
|
||||
definicao: "Controlador de camada de enlace de dados (Media Access Control) de rede cabeada integrado no silício, que exige apenas um chip transceptor físico externo (PHY como LAN8720 ou IP101) via interface RMII.",
|
||||
exemplo: "Conexão Ethernet RJ45 estável imune a ruídos de rádio para automação predial no ESP32 clássico e ESP32-P4.",
|
||||
},
|
||||
{
|
||||
termo: "Interface de Câmera DVP (8-bit / 16-bit)",
|
||||
definicao: "Barramento paralelo com sinais VSYNC, HREF, PCLK e barramento de dados com suporte a DMA para captura direta de frames de módulos de câmera populares (OV2640, OV5640).",
|
||||
exemplo: "Usado em placas ESP32-CAM e ESP32-S3-CAM para captura de fotos e streaming de vídeo MJPEG.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "energia",
|
||||
nome: "Gerenciamento de Energia & Sleep Modes",
|
||||
icone: "BatteryCharging",
|
||||
emoji: "🔋",
|
||||
cor: "teal",
|
||||
descricao: "Active Mode, Modem Sleep, Light Sleep, Deep Sleep, Hibernation, Brownout Detector e fontes de despertar.",
|
||||
termos: [
|
||||
{
|
||||
termo: "Active Mode",
|
||||
definicao: "Modo de operação normal onde a CPU executa instruções na frequência máxima e todos os periféricos e rádios estão prontos para uso, com consumo elétrico variando de 30 mA a ~240 mA (durante transmissões Wi-Fi).",
|
||||
exemplo: "ESP32 processando áudio, atualizando displays ou transmitindo dados de sensores em tempo real.",
|
||||
},
|
||||
{
|
||||
termo: "Modem Sleep",
|
||||
definicao: "Modo em que os circuitos de rádio Wi-Fi e Bluetooth são desligados temporariamente nos intervalos entre transmissões enquanto a CPU continua rodando seu código normalmente, reduzindo o consumo para ~20 a 40 mA.",
|
||||
exemplo: "Modo padrão em aplicações conectadas ao Wi-Fi que aguardam eventos de rede sem perder a associação ao roteador.",
|
||||
},
|
||||
{
|
||||
termo: "Light Sleep",
|
||||
definicao: "Modo de economia intermediário: a CPU tem seu clock pausado e os rádios são desligados, mas a memória SRAM interna, os periféricos e o estado das tarefas são preservados intactos. O chip acorda em menos de 1 ms.",
|
||||
exemplo: "Consumo de ~0.8 mA em dispositivos que precisam acordar rapidamente por interrupção de botão ou timer.",
|
||||
},
|
||||
{
|
||||
termo: "Deep Sleep",
|
||||
definicao: "Modo de sono profundo em que todos os domínios digitais e a CPU são desligados, mantendo alimentado apenas o domínio RTC (e opcionalmente a RTC Memory e o ULP). O consumo cai para 5 a 15 µA e o chip reinicia a execução ao acordar.",
|
||||
exemplo: "Estações meteorológicas remotas alimentadas por bateria e painel solar que realizam leituras a cada hora.",
|
||||
},
|
||||
{
|
||||
termo: "Hibernation Mode",
|
||||
definicao: "O estado de menor consumo elétrico do silício: desliga inclusive o oscilador de cristal do RTC e domínios lentos, mantendo apenas um circuito analógico de recuperação que acorda por botão externo ou reset.",
|
||||
exemplo: "Consumo residual de ~5 µA em dispositivos que operam por anos com bateria botão tipo moeda (CR2032).",
|
||||
},
|
||||
{
|
||||
termo: "Fontes de Despertar (Wakeup Sources)",
|
||||
definicao: "Eventos de hardware configurados para tirar o ESP32 do modo Deep Sleep ou Light Sleep: temporizadores RTC, pinos GPIO externos (EXT0 / EXT1), toque capacitivo ou sinal do coprocessador ULP.",
|
||||
exemplo: "`esp_sleep_enable_timer_wakeup(60 * 1000000)` para acordar exatamente a cada 60 segundos.",
|
||||
},
|
||||
{
|
||||
termo: "Brownout Detector",
|
||||
definicao: "Circuito comparador analógico interno de hardware que monitora a tensão de alimentação no pino 3V3 e força um reset de emergência seguro caso a tensão caia abaixo de ~2.8V para prevenir corrupção da memória Flash.",
|
||||
exemplo: "Protege o microcontrolador contra resets parciais causados por fontes fracas durante picos de transmissão de rádio.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "desenvolvimento",
|
||||
nome: "Firmware, Boot & Sistema Operacional",
|
||||
icone: "Code2",
|
||||
emoji: "🚀",
|
||||
cor: "rose",
|
||||
descricao: "Bootloader, FreeRTOS, macros IRAM_ATTR, partições da Flash, atualização OTA com Rollback e armazenamento NVS.",
|
||||
termos: [
|
||||
{
|
||||
termo: "Bootloader (First & Second Stage)",
|
||||
definicao: "Código que executa logo após o reset elétrico. O primeiro estágio reside na ROM do chip; o segundo estágio reside na Flash, valida a tabela de partições, checa as assinaturas de segurança e carrega o firmware do usuário.",
|
||||
exemplo: "Controla a alternância entre partições OTA e inicializa a memória PSRAM antes do `app_main`.",
|
||||
},
|
||||
{
|
||||
termo: "FreeRTOS (Sistema Operacional de Tempo Real)",
|
||||
definicao: "Kernel multitarefa preemptivo padrão do ESP-IDF que divide a CPU entre múltiplas tarefas (Tasks), filas de mensagens (Queues), semáforos, mutexes e timers de software com controle de prioridades.",
|
||||
exemplo: "`xTaskCreatePinnedToCore()` para alocar tarefas pesadas em núcleos específicos da CPU.",
|
||||
},
|
||||
{
|
||||
termo: "IRAM_ATTR & DRAM_ATTR",
|
||||
definicao: "Atributos especiais do compilador GCC para o ESP32 que forçam funções e variáveis a residirem na memória interna ultrarrápida IRAM/DRAM em vez da Flash externa, obrigatório para rotinas de interrupção (ISRs).",
|
||||
exemplo: "Evita que uma interrupção cause travamento (*Cache Error*) enquanto a Flash estiver ocupada gravando dados.",
|
||||
},
|
||||
{
|
||||
termo: "Tabela de Partições (partitions.csv)",
|
||||
definicao: "Arquivo de configuração que mapeia o espaço de armazenamento da memória Flash em blocos lógicos dedicados ao bootloader, dados NVS, arquivos LittleFS e múltiplas imagens de firmware (Factory, OTA_0, OTA_1).",
|
||||
exemplo: "Personalizado para acomodar firmwares grandes com bibliotecas de Bluetooth, Wi-Fi e criptografia.",
|
||||
},
|
||||
{
|
||||
termo: "OTA (Over-The-Air Update) com Rollback",
|
||||
definicao: "Atualização sem fio de firmware onde a nova versão é gravada em uma partição secundária. Se o novo firmware falhar ao inicializar, o sistema reverte automaticamente (*Rollback*) para a versão funcional anterior.",
|
||||
exemplo: "`esp_ota_mark_app_valid_cancel_rollback()` confirma que a nova atualização está saudável em campo.",
|
||||
},
|
||||
{
|
||||
termo: "NVS (Non-Volatile Storage) & NVS Encryption",
|
||||
definicao: "Mecanismo estruturado de chave-valor na memória Flash para persistir credenciais de rede, parâmetros de calibração e contadores, com suporte a criptografia em hardware via chave AES nos eFuses.",
|
||||
exemplo: "Salvar nome de rede Wi-Fi e senhas criptografadas para reconexão automática após desligamento.",
|
||||
},
|
||||
{
|
||||
termo: "LittleFS & SPIFFS",
|
||||
definicao: "Sistemas de arquivos desenvolvidos para memórias Flash com nivelamento de desgaste (*wear leveling*), permitindo que a aplicação leia e grave arquivos como páginas HTML, certificados SSL e logs.",
|
||||
exemplo: "Armazenar páginas HTML/CSS do servidor web embutido do ESP32 para configuração de rede via navegador.",
|
||||
},
|
||||
{
|
||||
termo: "JTAG & OpenOCD",
|
||||
definicao: "Padrão de depuração em nível de hardware que permite pausar a CPU, colocar breakpoints e inspecionar registradores e variáveis em tempo real no VS Code ou Eclipse via sondas USB-JTAG.",
|
||||
exemplo: "Depuração de crashes complexos e ponteiros nulos sem depender apenas de comandos `Serial.println()`.",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* Conhecimento de domínio da busca inteligente.
|
||||
*
|
||||
* Sem dependências nem alias de import: roda no servidor (montando o índice),
|
||||
* no navegador (interpretando a consulta) e em scripts de teste no Node.
|
||||
*
|
||||
* Todos os textos de `termos` já estão normalizados (minúsculos, sem acento).
|
||||
*/
|
||||
|
||||
export const normalizar = (s = "") =>
|
||||
String(s)
|
||||
.toLowerCase()
|
||||
.normalize("NFD")
|
||||
.replace(/[\u0300-\u036f]/g, "");
|
||||
|
||||
/**
|
||||
* Reconhece pinos ocupados por flash/PSRAM com base no que o diagrama diz.
|
||||
* "forte": o pino é consumido pela memória (ou é a alimentação dela).
|
||||
* "fraco": só é afetado em certos modos (ex.: SPI de 8 linhas/octal).
|
||||
* Avisos genéricos de tensão mínima ("para chips com flash integrada...") não contam.
|
||||
*/
|
||||
const nivelMemoria = (palavra) => (p) => {
|
||||
const citam = p._avs.filter((a) => a.includes(palavra) && !/^para chips (com|sem)/.test(a));
|
||||
if (citam.some((a) => /(utilizad|dedicad|conectad)/.test(a) && !/a menos que/.test(a))) return "forte";
|
||||
if (p._fn.some((f) => /alimentacao/.test(f) && f.includes(palavra))) return "forte";
|
||||
if (citam.length) return "fraco";
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Assuntos que o usuário pode citar. Cada um sabe:
|
||||
* - termos: como as pessoas escrevem (sinônimos, siglas, plurais comuns);
|
||||
* - pinoCats / pinoRe: como reconhecer os pinos relacionados no diagrama;
|
||||
* - pinoRotulo: frase usada no título do resultado de pinos.
|
||||
* Os dados de especificação ligam-se aos assuntos por SPEC_CAMPOS.
|
||||
*/
|
||||
export const TOPICOS = [
|
||||
{ id: "flash", nome: "Flash", termos: ["flash", "memoria flash", "spi flash", "armazenamento", "firmware", "rom externa"], pinoNivel: nivelMemoria("flash"), pinoRotulo: "ligados à memória flash" },
|
||||
{ id: "psram", nome: "PSRAM", termos: ["psram", "ram externa", "spiram"], pinoNivel: nivelMemoria("psram"), pinoRotulo: "ligados à PSRAM" },
|
||||
{ id: "memoria", nome: "Memória", termos: ["memoria", "sram", "heap", "rtc ram", "kb de ram", "memoria interna", "ram"], pinoRotulo: "" },
|
||||
{ id: "wifi", nome: "Wi-Fi", termos: ["wifi", "wi-fi", "wireless", "sem fio", "802.11", "wifi6", "wifi 6", "wi-fi 6"], pinoCats: ["Antena"], pinoRotulo: "de antena e rádio" },
|
||||
{ id: "bluetooth", nome: "Bluetooth", termos: ["bluetooth", "ble", "bt", "bluetooth le", "mesh"], pinoCats: ["Antena"], pinoRotulo: "de antena e rádio" },
|
||||
{ id: "zigbee", nome: "Zigbee/Thread", termos: ["zigbee", "thread", "802.15.4", "ieee 802.15.4"], pinoRotulo: "" },
|
||||
{ id: "matter", nome: "Matter", termos: ["matter", "casa inteligente", "smart home"], pinoRotulo: "" },
|
||||
{ id: "ethernet", nome: "Ethernet", termos: ["ethernet", "rmii", "cabo de rede", "lan"], pinoCats: ["Ethernet"], pinoRotulo: "de Ethernet" },
|
||||
{ id: "can", nome: "CAN / TWAI", termos: ["can", "twai", "can bus", "canbus", "can fd"], pinoRe: /twai|\bcan\b/, pinoRotulo: "de CAN/TWAI" },
|
||||
{ id: "usb", nome: "USB", termos: ["usb", "otg", "usb serial", "usb otg", "hid", "cdc"], pinoCats: ["USB"], pinoRotulo: "de USB" },
|
||||
{ id: "jtag", nome: "JTAG / Depuração", termos: ["jtag", "debug", "depuracao", "depurar", "openocd", "gdb"], pinoCats: ["JTAG"], pinoRotulo: "de JTAG" },
|
||||
{ id: "adc", nome: "ADC", termos: ["adc", "analogico", "entrada analogica", "conversor analogico", "analogread", "saradc"], pinoCats: ["ADC"], pinoRotulo: "com ADC" },
|
||||
{ id: "dac", nome: "DAC", termos: ["dac", "saida analogica", "conversor digital"], pinoCats: ["DAC"], pinoRotulo: "com DAC" },
|
||||
{ id: "touch", nome: "Touch capacitivo", termos: ["touch", "capacitivo", "toque", "touchpad", "sensor de toque"], pinoCats: ["Touch"], pinoRotulo: "de touch capacitivo" },
|
||||
{ id: "uart", nome: "UART", termos: ["uart", "serial", "tx", "rx", "txd", "rxd", "porta serial"], pinoCats: ["UART"], pinoRotulo: "de UART" },
|
||||
{ id: "spi", nome: "SPI", termos: ["spi", "mosi", "miso", "sclk", "barramento spi"], pinoCats: ["SPI"], pinoRotulo: "de SPI" },
|
||||
{ id: "i2c", nome: "I2C", termos: ["i2c", "sda", "scl", "twi", "iic"], pinoCats: ["I2C"], pinoRotulo: "de I2C" },
|
||||
{ id: "i2s", nome: "I2S", termos: ["i2s", "audio", "som", "microfone", "pdm", "codec"], pinoRe: /i2s|\bpdm\b/, pinoRotulo: "de I2S/áudio" },
|
||||
{ id: "pwm", nome: "PWM", termos: ["pwm", "ledc", "mcpwm", "servo", "dimmer"], pinoRe: /ledc|pwm/, pinoRotulo: "de PWM" },
|
||||
{ id: "sd", nome: "Cartão SD / SDIO", termos: ["sd", "sdio", "sd card", "sdcard", "cartao sd", "microsd", "sdmmc", "mmc"], pinoCats: ["SD"], pinoRe: /sdio|sdmmc|\bsd\b/, pinoRotulo: "de cartão SD/SDIO" },
|
||||
{ id: "camera", nome: "Câmera", termos: ["camera", "cam", "dvp", "csi", "mipi csi", "ov2640", "video"], pinoCats: ["CSI"], pinoRe: /\bcam\b|dvp|cam_/, pinoRotulo: "de câmera" },
|
||||
{ id: "lcd", nome: "Display / LCD", termos: ["lcd", "display", "tela", "dsi", "mipi dsi", "oled", "tft", "lvgl", "rgb"], pinoCats: ["DSI"], pinoRe: /lcd/, pinoRotulo: "de display/LCD" },
|
||||
{ id: "strapping", nome: "Boot / Strapping", termos: ["strapping", "boot", "bootstrap", "modo de boot", "download mode", "modo de gravacao", "inicializacao"], pinoCats: ["Strapping"], pinoRotulo: "de strapping (modo de boot)" },
|
||||
{ id: "energia_pinos", nome: "Alimentação", termos: ["alimentacao", "vdd", "3v3", "3.3v", "tensao", "regulador", "ldo", "fonte"], pinoCats: ["Power"], pinoRotulo: "de alimentação" },
|
||||
{ id: "clock", nome: "Clock / Cristal", termos: ["clock", "xtal", "cristal", "oscilador", "32khz", "40mhz"], pinoCats: ["Clock"], pinoRotulo: "de clock/cristal" },
|
||||
{ id: "gpio", nome: "GPIO", termos: ["gpio", "entradas e saidas"], pinoCats: ["GPIO"], pinoRotulo: "de GPIO" },
|
||||
{ id: "baixo_consumo", nome: "Baixo consumo / ULP", termos: ["ulp", "lp core", "lp cpu", "coprocessador", "lp gpio", "low power", "rtc gpio"], pinoCats: ["Low Power"], pinoRotulo: "de baixo consumo (LP/RTC)" },
|
||||
{ id: "antena", nome: "Antena / RF", termos: ["antena", "rf", "radiofrequencia", "ipex"], pinoCats: ["Antena"], pinoRotulo: "de antena/RF" },
|
||||
{ id: "seguranca", nome: "Segurança", termos: ["seguranca", "secure boot", "criptografia", "encriptacao", "aes", "sha", "rsa", "hmac", "ecdsa", "efuse", "tee", "trng", "rng", "hsm", "protecao"], pinoRotulo: "" },
|
||||
{ id: "consumo", nome: "Consumo de energia", termos: ["consumo", "bateria", "deep sleep", "light sleep", "sleep", "modem sleep", "corrente", "miliamperes", "autonomia", "economia de energia", "low power mode"], pinoRotulo: "" },
|
||||
{ id: "temperatura", nome: "Temperatura", termos: ["temperatura", "calor", "graus", "faixa de temperatura", "industrial"], pinoRotulo: "" },
|
||||
{ id: "ia", nome: "IA / Aceleração", termos: ["ia", "ai", "machine learning", "ml", "tinyml", "vetorial", "inteligencia artificial", "rede neural", "esp-nn", "esp-dl"], pinoRotulo: "" },
|
||||
{ id: "processador", nome: "Processador", termos: ["processador", "cpu", "nucleo", "nucleos", "core", "dual core", "single core", "arquitetura", "xtensa", "risc-v", "riscv"], pinoRotulo: "" },
|
||||
{ id: "frequencia", nome: "Frequência", termos: ["frequencia", "mhz", "velocidade", "desempenho", "performance"], pinoRotulo: "" },
|
||||
{ id: "ferramentas", nome: "Ferramentas / SDK", termos: ["esp-idf", "idf", "arduino", "sdk", "toolchain", "versao do idf"], pinoRotulo: "" },
|
||||
{ id: "encapsulamento", nome: "Módulos e encapsulamento", termos: ["modulo", "modulos", "encapsulamento", "package", "qfn", "wroom", "wrover", "mini-1"], pinoRotulo: "" },
|
||||
];
|
||||
|
||||
/**
|
||||
* Campos de public/series.json que respondem a cada assunto.
|
||||
* `campo` aceita caminho com ponto (seguranca.aes). `secao` é o id da âncora
|
||||
* na página /series/[key].
|
||||
*/
|
||||
export const SPEC_CAMPOS = [
|
||||
{ campo: "arquitetura", label: "Arquitetura", secao: "processador", topicos: ["processador"] },
|
||||
{ campo: "nucleos", label: "Núcleos", secao: "processador", topicos: ["processador"] },
|
||||
{ campo: "frequencia", label: "Frequência", secao: "processador", topicos: ["frequencia", "processador"] },
|
||||
{ campo: "coprocessador_ulp", label: "Coprocessador ULP", secao: "processador", topicos: ["baixo_consumo"] },
|
||||
{ campo: "aceleradores_ia", label: "Aceleradores de IA", secao: "processador", topicos: ["ia"] },
|
||||
|
||||
{ campo: "wifi", label: "Wi-Fi", secao: "conectividade", topicos: ["wifi"] },
|
||||
{ campo: "bluetooth", label: "Bluetooth", secao: "conectividade", topicos: ["bluetooth"] },
|
||||
{ campo: "zigbee_thread", label: "Zigbee/Thread", secao: "conectividade", topicos: ["zigbee"] },
|
||||
{ campo: "matter", label: "Matter", secao: "conectividade", topicos: ["matter"] },
|
||||
{ campo: "ethernet", label: "Ethernet", secao: "conectividade", topicos: ["ethernet"] },
|
||||
{ campo: "ethernet_mac", label: "Ethernet MAC", secao: "conectividade", topicos: ["ethernet"] },
|
||||
{ campo: "can", label: "CAN", secao: "conectividade", topicos: ["can"] },
|
||||
|
||||
{ campo: "memoria_sram", label: "SRAM", secao: "memoria", topicos: ["memoria"] },
|
||||
{ campo: "memoria_sram_rtc", label: "SRAM RTC", secao: "memoria", topicos: ["memoria", "baixo_consumo"] },
|
||||
{ campo: "memoria_rom", label: "ROM", secao: "memoria", topicos: ["memoria"] },
|
||||
{ campo: "flash_externa", label: "Flash externa", secao: "memoria", topicos: ["flash", "memoria"] },
|
||||
{ campo: "psram_externa", label: "PSRAM externa", secao: "memoria", topicos: ["psram", "memoria"] },
|
||||
|
||||
{ campo: "gpio", label: "GPIO", secao: "perifericos", topicos: ["gpio"] },
|
||||
{ campo: "adc", label: "ADC", secao: "perifericos", topicos: ["adc"] },
|
||||
{ campo: "dac", label: "DAC", secao: "perifericos", topicos: ["dac"] },
|
||||
{ campo: "touch", label: "Touch", secao: "perifericos", topicos: ["touch"] },
|
||||
{ campo: "uart", label: "UART", secao: "perifericos", topicos: ["uart"] },
|
||||
{ campo: "spi", label: "SPI", secao: "perifericos", topicos: ["spi", "flash"] },
|
||||
{ campo: "i2c", label: "I2C", secao: "perifericos", topicos: ["i2c"] },
|
||||
{ campo: "i2s", label: "I2S", secao: "perifericos", topicos: ["i2s"] },
|
||||
{ campo: "pwm", label: "PWM", secao: "perifericos", topicos: ["pwm"] },
|
||||
{ campo: "usb", label: "USB", secao: "perifericos", topicos: ["usb"] },
|
||||
{ campo: "lcd", label: "LCD", secao: "interfaces", topicos: ["lcd"] },
|
||||
{ campo: "camera", label: "Câmera", secao: "interfaces", topicos: ["camera"] },
|
||||
{ campo: "mipi_csi", label: "MIPI CSI", secao: "interfaces", topicos: ["camera"] },
|
||||
{ campo: "mipi_dsi", label: "MIPI DSI", secao: "interfaces", topicos: ["lcd"] },
|
||||
{ campo: "sdio", label: "SDIO", secao: "interfaces", topicos: ["sd"] },
|
||||
{ campo: "sensor_temperatura", label: "Sensor de temperatura", secao: "interfaces", topicos: ["temperatura"] },
|
||||
|
||||
{ campo: "seguranca.aes", label: "AES", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.sha", label: "SHA", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.rsa", label: "RSA", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.ecc", label: "ECC", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.ecdsa", label: "ECDSA", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.hmac", label: "HMAC", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.assinatura_digital", label: "Assinatura digital", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.rng", label: "Gerador aleatório", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.criptografia_flash", label: "Criptografia de flash", secao: "seguranca", topicos: ["seguranca", "flash"] },
|
||||
{ campo: "seguranca.secure_boot", label: "Secure Boot", secao: "seguranca", topicos: ["seguranca", "strapping"] },
|
||||
|
||||
{ campo: "temperatura_operacao", label: "Temperatura de operação", secao: "temperatura", topicos: ["temperatura"] },
|
||||
{ campo: "temperatura_armazenamento", label: "Temperatura de armazenamento", secao: "temperatura", topicos: ["temperatura"] },
|
||||
|
||||
{ campo: "esp_idf_minimo", label: "ESP-IDF mínimo", secao: "ferramentas", topicos: ["ferramentas"] },
|
||||
{ campo: "arduino_core", label: "Core Arduino", secao: "ferramentas", topicos: ["ferramentas"] },
|
||||
{ campo: "depuracao", label: "Depuração", secao: "ferramentas", topicos: ["jtag", "ferramentas"] },
|
||||
{ campo: "encapsulamento", label: "Encapsulamento", secao: "ferramentas", topicos: ["encapsulamento"] },
|
||||
{ campo: "modulos", label: "Módulos", secao: "ferramentas", topicos: ["encapsulamento"] },
|
||||
];
|
||||
|
||||
const ROTULOS_ENERGIA = {
|
||||
active: "Ativo",
|
||||
modem_sleep: "Modem Sleep",
|
||||
light_sleep: "Light Sleep",
|
||||
deep_sleep: "Deep Sleep",
|
||||
hibernation: "Hibernação",
|
||||
};
|
||||
|
||||
const pegar = (obj, caminho) => caminho.split(".").reduce((o, k) => (o == null ? o : o[k]), obj);
|
||||
|
||||
/**
|
||||
* Monta, para cada série, a lista plana de especificações (com os assuntos a
|
||||
* que respondem) e os pinos do diagrama. É o que o navegador baixa.
|
||||
*
|
||||
* @param {Record<string, object>} series conteúdo de public/series.json
|
||||
* @param {Record<string, object[]>} conexoes pinos por série (public/conexoes)
|
||||
*/
|
||||
export function montarConhecimento(series, conexoes) {
|
||||
const saida = {};
|
||||
for (const [chave, s] of Object.entries(series)) {
|
||||
const specs = [];
|
||||
for (const c of SPEC_CAMPOS) {
|
||||
const valor = pegar(s, c.campo);
|
||||
if (valor == null || valor === "") continue;
|
||||
specs.push({ label: c.label, valor: String(valor), secao: c.secao, topicos: c.topicos });
|
||||
}
|
||||
for (const [modo, valor] of Object.entries(s.consumo_energia ?? {})) {
|
||||
const base = modo.replace(/_cpu.*|_wifi.*/, "");
|
||||
const label = ROTULOS_ENERGIA[modo] ?? ROTULOS_ENERGIA[base] ?? modo.replace(/_/g, " ");
|
||||
specs.push({ label: `Consumo: ${label}`, valor: String(valor), secao: "energia", topicos: ["consumo"] });
|
||||
}
|
||||
saida[chave] = {
|
||||
nome: s.nome_completo ?? chave,
|
||||
specs,
|
||||
pinos: (conexoes[chave] ?? []).map((p) => ({
|
||||
n: String(p.numero),
|
||||
nome: p.nome,
|
||||
f: p.funcoes ?? [],
|
||||
c: p.categorias ?? [],
|
||||
a: p.avisos ?? [],
|
||||
})),
|
||||
};
|
||||
}
|
||||
return saida;
|
||||
}
|
||||
+60
-17
@@ -1,9 +1,17 @@
|
||||
import seriesData from "@/public/series.json";
|
||||
import frameworksData from "@/public/frameworks.json";
|
||||
import { categoriasGlossario } from "@/lib/glossarioData";
|
||||
import { errosCatalogo } from "@/lib/diagnosticoData";
|
||||
import { COMPONENTES_REGISTRY } from "@/lib/componentRegistryData";
|
||||
import { montarConhecimento } from "@/lib/searchTopics";
|
||||
import seriesDataPt from "@/public/series.json";
|
||||
import frameworksDataPt from "@/public/frameworks.json";
|
||||
import { categoriasGlossario as glossarioPt } from "@/lib/glossarioData";
|
||||
import { errosCatalogo as errosPt } from "@/lib/diagnosticoData";
|
||||
import { COMPONENTES_REGISTRY as componentesPt } from "@/lib/componentRegistryData";
|
||||
import { montarConhecimento as montarConhecimentoPt } from "@/lib/searchTopics";
|
||||
|
||||
import seriesDataEn from "@/data/en/series.json";
|
||||
import frameworksDataEn from "@/data/en/frameworks.json";
|
||||
import { categoriasGlossario as glossarioEn } from "@/lib/data/en/glossario";
|
||||
import { errosCatalogo as errosEn } from "@/lib/data/en/diagnostico";
|
||||
import { COMPONENTES_REGISTRY as componentesEn } from "@/lib/data/en/componentes";
|
||||
import { montarConhecimento as montarConhecimentoEn } from "@/lib/data/en/topicos";
|
||||
|
||||
import { readFileSync, existsSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
@@ -15,7 +23,7 @@ import path from "node:path";
|
||||
* `keywords` guarda texto extra pesquisável (não exibido).
|
||||
*/
|
||||
|
||||
const PAGINAS = [
|
||||
const PAGINAS_PT = [
|
||||
{ titulo: "Início", descricao: "Página inicial do ESPDocs", href: "/", keywords: "home inicio" },
|
||||
{ titulo: "Todas as Séries", descricao: "Pinouts, especificações e restrições de cada série ESP32", href: "/series", keywords: "chips pinout especificações" },
|
||||
{ titulo: "Comparador de Séries", descricao: "Compare até 4 modelos lado a lado", href: "/comparacao", keywords: "comparar comparação versus" },
|
||||
@@ -29,12 +37,41 @@ const PAGINAS = [
|
||||
{ titulo: "Sobre o Projeto", descricao: "História, autor e Ciência Embarcada", href: "/sobre", keywords: "autor contato" },
|
||||
];
|
||||
|
||||
const PAGINAS_EN = [
|
||||
{ titulo: "Home", descricao: "ESPDocs homepage", href: "/en", keywords: "home" },
|
||||
{ titulo: "All Series", descricao: "Pinouts, specifications and restrictions for each ESP32 series", href: "/en/series", keywords: "chips pinout specifications" },
|
||||
{ titulo: "Series Comparator", descricao: "Compare up to 4 models side by side", href: "/en/compare", keywords: "compare comparison versus" },
|
||||
{ titulo: "Board Catalog", descricao: "Development boards, pinouts and purchasing", href: "/en/catalog", keywords: "boards dev boards devkit buy" },
|
||||
{ titulo: "Smart Selector", descricao: "Find the ideal chip for your project", href: "/en/selector", keywords: "quiz choose recommend selector" },
|
||||
{ titulo: "Error Diagnostics", descricao: "Troubleshoot brownout, bootloop, WDT and crashes", href: "/en/diagnostics", keywords: "error problem bug crash issue" },
|
||||
{ titulo: "Frameworks & SDKs", descricao: "ESP-IDF, Arduino, Rust, RainMaker and more", href: "/en/frameworks", keywords: "sdk" },
|
||||
{ titulo: "Component Registry", descricao: "Driver catalog and idf_component.yml generator", href: "/en/components", keywords: "libraries drivers yml components" },
|
||||
{ titulo: "Technical Glossary", descricao: "Essential hardware and software concepts", href: "/en/glossary", keywords: "terms dictionary definition meaning" },
|
||||
{ titulo: "About the Project", descricao: "History, author and open source", href: "/en/about", keywords: "author contact" },
|
||||
];
|
||||
|
||||
const cortar = (texto = "", max = 140) => (texto.length > max ? `${texto.slice(0, max - 1).trimEnd()}…` : texto);
|
||||
|
||||
export function construirIndiceBusca() {
|
||||
export function construirIndiceBusca(locale = "pt") {
|
||||
const isEn = locale === "en";
|
||||
const paginas = isEn ? PAGINAS_EN : PAGINAS_PT;
|
||||
const seriesData = isEn ? seriesDataEn : seriesDataPt;
|
||||
const frameworksData = isEn ? frameworksDataEn : frameworksDataPt;
|
||||
const categoriasGlossario = isEn ? glossarioEn : glossarioPt;
|
||||
const errosCatalogo = isEn ? errosEn : errosPt;
|
||||
const componentes = isEn ? componentesEn : componentesPt;
|
||||
const montarConhecimento = isEn ? montarConhecimentoEn : montarConhecimentoPt;
|
||||
|
||||
const prefixo = isEn ? "/en" : "";
|
||||
const slugSeries = `${prefixo}/series`;
|
||||
const slugFrameworks = `${prefixo}/frameworks`;
|
||||
const slugGlossario = isEn ? "/en/glossary" : "/glossario";
|
||||
const slugDiagnostico = isEn ? "/en/diagnostics" : "/diagnostico";
|
||||
const slugComponentes = isEn ? "/en/components" : "/componentes";
|
||||
|
||||
const itens = [];
|
||||
|
||||
for (const p of PAGINAS) {
|
||||
for (const p of paginas) {
|
||||
itens.push({ tipo: "pagina", ...p, keywords: p.keywords });
|
||||
}
|
||||
|
||||
@@ -43,7 +80,7 @@ export function construirIndiceBusca() {
|
||||
tipo: "serie",
|
||||
titulo: chave,
|
||||
descricao: cortar(`${s.nome_completo ?? ""} — ${s.descricao ?? ""}`),
|
||||
href: `/series/${chave}`,
|
||||
href: `${slugSeries}/${chave}`,
|
||||
keywords: [s.arquitetura, s.wifi, s.bluetooth, s.frequencia, s.nucleos].filter(Boolean).join(" "),
|
||||
});
|
||||
}
|
||||
@@ -53,7 +90,7 @@ export function construirIndiceBusca() {
|
||||
tipo: "framework",
|
||||
titulo: f.nome ?? chave,
|
||||
descricao: cortar(`${f.nome_completo ?? ""} — ${f.descricao ?? ""}`),
|
||||
href: `/frameworks/${encodeURIComponent(chave)}`,
|
||||
href: `${slugFrameworks}/${encodeURIComponent(chave)}`,
|
||||
keywords: [f.linguagem, f.tipo, f.funcao_principal].filter(Boolean).join(" "),
|
||||
});
|
||||
}
|
||||
@@ -65,7 +102,7 @@ export function construirIndiceBusca() {
|
||||
tipo: "glossario",
|
||||
titulo: t.termo,
|
||||
descricao: cortar(t.definicao),
|
||||
href: `/glossario#${slug}`,
|
||||
href: `${slugGlossario}#${slug}`,
|
||||
keywords: [cat.nome, t.exemplo].filter(Boolean).join(" "),
|
||||
});
|
||||
}
|
||||
@@ -76,25 +113,31 @@ export function construirIndiceBusca() {
|
||||
tipo: "erro",
|
||||
titulo: e.titulo,
|
||||
descricao: cortar(e.resumo),
|
||||
href: `/diagnostico#${e.id}`,
|
||||
href: `${slugDiagnostico}#${e.id}`,
|
||||
keywords: [e.logSerial, ...(e.sintomas ?? [])].filter(Boolean).join(" "),
|
||||
});
|
||||
}
|
||||
|
||||
for (const c of COMPONENTES_REGISTRY) {
|
||||
for (const c of componentes) {
|
||||
itens.push({
|
||||
tipo: "componente",
|
||||
titulo: c.titulo,
|
||||
descricao: cortar(c.descricao),
|
||||
href: "/componentes",
|
||||
href: slugComponentes,
|
||||
keywords: [c.name, c.namespace, ...(c.tags ?? [])].filter(Boolean).join(" "),
|
||||
});
|
||||
}
|
||||
|
||||
const conexoes = {};
|
||||
for (const chave of Object.keys(seriesData)) {
|
||||
const arquivo = path.join(process.cwd(), "public", "conexoes", `${chave}.json`);
|
||||
if (existsSync(arquivo)) conexoes[chave] = JSON.parse(readFileSync(arquivo, "utf8"));
|
||||
const pastaConexoes = isEn ? path.join(process.cwd(), "data", "en", "conexoes") : path.join(process.cwd(), "public", "conexoes");
|
||||
const arquivo = path.join(pastaConexoes, `${chave}.json`);
|
||||
if (existsSync(arquivo)) {
|
||||
conexoes[chave] = JSON.parse(readFileSync(arquivo, "utf8"));
|
||||
} else {
|
||||
const fallback = path.join(process.cwd(), "public", "conexoes", `${chave}.json`);
|
||||
if (existsSync(fallback)) conexoes[chave] = JSON.parse(readFileSync(fallback, "utf8"));
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
+105
-48
@@ -6,6 +6,8 @@
|
||||
* nascendo sem título próprio.
|
||||
*/
|
||||
|
||||
import { ENABLED_LOCALES, getLocalizedHref } from "@/i18n/links";
|
||||
|
||||
export const SITE = {
|
||||
url: "https://espdocs.cienciaembarcada.com.br",
|
||||
nome: "ESPDocs",
|
||||
@@ -28,16 +30,49 @@ export const SITE = {
|
||||
* Usar isto em vez de escrever o objeto à mão garante que nenhuma página fique
|
||||
* sem canonical ou sem og:title.
|
||||
*/
|
||||
export function paginaMeta({ titulo, descricao, caminho, keywords = [], tipo = "website" }) {
|
||||
const url = `${SITE.url}${caminho}`;
|
||||
export function paginaMeta({ titulo, descricao, caminho, keywords = [], tipo = "website", locale = "pt" }) {
|
||||
const currentLocale = locale || "pt";
|
||||
const basePath = caminho.startsWith("/") ? caminho : `/${caminho}`;
|
||||
const canonicalPath = getLocalizedHref(`/pt${basePath}`, currentLocale);
|
||||
const url = `${SITE.url}${canonicalPath}`;
|
||||
|
||||
const languages = {};
|
||||
for (const loc of ENABLED_LOCALES) {
|
||||
if (basePath === "/livro" && loc !== "pt") continue;
|
||||
const locHref = getLocalizedHref(`/pt${basePath}`, loc);
|
||||
const langKey = loc === "pt" ? "pt-BR" : loc;
|
||||
languages[langKey] = `${SITE.url}${locHref}`;
|
||||
}
|
||||
if (ENABLED_LOCALES.includes("en") && basePath !== "/livro") {
|
||||
languages["x-default"] = `${SITE.url}${getLocalizedHref(`/pt${basePath}`, "en")}`;
|
||||
}
|
||||
|
||||
const ogLocaleMap = {
|
||||
pt: "pt_BR",
|
||||
en: "en_US",
|
||||
es: "es_419",
|
||||
fr: "fr_FR",
|
||||
de: "de_DE",
|
||||
"zh-CN": "zh_CN",
|
||||
};
|
||||
|
||||
const alternateLocales = ENABLED_LOCALES
|
||||
.filter((l) => l !== currentLocale && (basePath !== "/livro" || l === "pt"))
|
||||
.map((l) => ogLocaleMap[l])
|
||||
.filter(Boolean);
|
||||
|
||||
return {
|
||||
title: titulo,
|
||||
description: descricao,
|
||||
keywords,
|
||||
alternates: { canonical: caminho },
|
||||
alternates: {
|
||||
canonical: canonicalPath,
|
||||
languages: Object.keys(languages).length > 1 ? languages : undefined,
|
||||
},
|
||||
openGraph: {
|
||||
type: tipo,
|
||||
locale: "pt_BR",
|
||||
locale: ogLocaleMap[currentLocale] || "pt_BR",
|
||||
alternateLocale: alternateLocales.length > 0 ? alternateLocales : undefined,
|
||||
url,
|
||||
siteName: SITE.nome,
|
||||
title: `${titulo} · ${SITE.nome}`,
|
||||
@@ -57,23 +92,25 @@ export function paginaMeta({ titulo, descricao, caminho, keywords = [], tipo = "
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
export const jsonLd = {
|
||||
siteESociedade() {
|
||||
siteESociedade(locale = "pt") {
|
||||
const isEn = locale === "en";
|
||||
return {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "WebSite",
|
||||
"@id": `${SITE.url}/#site`,
|
||||
url: SITE.url,
|
||||
url: `${SITE.url}/${locale}`,
|
||||
name: SITE.nome,
|
||||
inLanguage: "pt-BR",
|
||||
description:
|
||||
"Documentação do ecossistema ESP32 em português brasileiro: especificações, pinagem, comparação e seleção de séries.",
|
||||
publisher: { "@id": `${SITE.url}/#organizacao` },
|
||||
inLanguage: isEn ? "en" : "pt-BR",
|
||||
description: isEn
|
||||
? "ESP32 ecosystem documentation: specifications, pinouts, comparison, and series selection."
|
||||
: "Documentação do ecossistema ESP32 em português brasileiro: especificações, pinagem, comparação e seleção de séries.",
|
||||
publisher: { "@id": `${SITE.url}/#${isEn ? "organization" : "organizacao"}` },
|
||||
},
|
||||
{
|
||||
"@type": "Organization",
|
||||
"@id": `${SITE.url}/#organizacao`,
|
||||
"@id": `${SITE.url}/#${isEn ? "organization" : "organizacao"}`,
|
||||
name: "Ciência Embarcada",
|
||||
url: SITE.blog,
|
||||
logo: {
|
||||
@@ -87,7 +124,7 @@ export const jsonLd = {
|
||||
},
|
||||
{
|
||||
"@type": "Person",
|
||||
"@id": `${SITE.url}/#autor`,
|
||||
"@id": `${SITE.url}/#${isEn ? "author" : "autor"}`,
|
||||
name: SITE.autor,
|
||||
url: SITE.autorUrl,
|
||||
email: SITE.autorEmail,
|
||||
@@ -112,44 +149,51 @@ export const jsonLd = {
|
||||
},
|
||||
|
||||
/** Documentação e ficha técnica da série como TechArticle para o Google. */
|
||||
serie(chave, serie) {
|
||||
serie(chave, serie, locale = "pt") {
|
||||
const isEn = locale === "en";
|
||||
const prop = (nome, valor) =>
|
||||
valor ? { "@type": "PropertyValue", name: nome, value: String(valor) } : null;
|
||||
|
||||
const propriedades = [
|
||||
prop("Fabricante", "Espressif Systems"),
|
||||
prop("Arquitetura", serie.arquitetura),
|
||||
prop("Núcleos", serie.nucleos),
|
||||
prop("Frequência máxima", serie.frequencia),
|
||||
prop(isEn ? "Manufacturer" : "Fabricante", "Espressif Systems"),
|
||||
prop(isEn ? "Architecture" : "Arquitetura", serie.arquitetura),
|
||||
prop(isEn ? "Cores" : "Núcleos", serie.nucleos),
|
||||
prop(isEn ? "Max frequency" : "Frequência máxima", serie.frequencia),
|
||||
prop("SRAM", serie.memoria_sram),
|
||||
prop("RTC SRAM", serie.memoria_sram_rtc),
|
||||
prop("Flash suportada", serie.flash_suportada),
|
||||
prop("PSRAM suportada", serie.psram_suportada),
|
||||
prop(isEn ? "Supported Flash" : "Flash suportada", serie.flash_suportada),
|
||||
prop(isEn ? "Supported PSRAM" : "PSRAM suportada", serie.psram_suportada),
|
||||
prop("GPIO", serie.gpio),
|
||||
prop("Wi-Fi", serie.wifi),
|
||||
prop("Bluetooth", serie.bluetooth),
|
||||
prop("Zigbee / Thread / 802.15.4", serie.zigbee_thread),
|
||||
prop("Encapsulamento", serie.encapsulamento),
|
||||
prop("ESP-IDF mínimo", serie.esp_idf_minimo),
|
||||
prop(isEn ? "Package" : "Encapsulamento", serie.encapsulamento),
|
||||
prop(isEn ? "Minimum ESP-IDF" : "ESP-IDF mínimo", serie.esp_idf_minimo),
|
||||
].filter(Boolean);
|
||||
|
||||
const imagem = serie.placa
|
||||
? `${SITE.url}${serie.placa}`
|
||||
: `${SITE.url}/opengraph-image.png`;
|
||||
|
||||
const basePath = isEn ? `/en/series/${chave}` : `/series/${chave}`;
|
||||
|
||||
return {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "TechArticle",
|
||||
"@id": `${SITE.url}/series/${chave}#artigo`,
|
||||
headline: `${serie.nome_completo || chave}: especificações e pinagem`,
|
||||
name: `${serie.nome_completo || chave} - Documentação Técnica e Especificações`,
|
||||
"@id": `${SITE.url}${basePath}#${isEn ? "article" : "artigo"}`,
|
||||
headline: isEn
|
||||
? `${serie.nome_completo || chave}: specifications and pinout`
|
||||
: `${serie.nome_completo || chave}: especificações e pinagem`,
|
||||
name: isEn
|
||||
? `${serie.nome_completo || chave} - Technical Documentation and Specifications`
|
||||
: `${serie.nome_completo || chave} - Documentação Técnica e Especificações`,
|
||||
description: serie.descricao,
|
||||
image: [imagem],
|
||||
inLanguage: "pt-BR",
|
||||
inLanguage: isEn ? "en" : "pt-BR",
|
||||
datePublished: "2026-08-25T00:00:00.000Z",
|
||||
dateModified: new Date().toISOString(),
|
||||
mainEntityOfPage: `${SITE.url}/series/${chave}`,
|
||||
url: `${SITE.url}/series/${chave}`,
|
||||
mainEntityOfPage: `${SITE.url}${basePath}`,
|
||||
url: `${SITE.url}${basePath}`,
|
||||
author: {
|
||||
"@type": "Person",
|
||||
name: SITE.autor,
|
||||
@@ -176,20 +220,26 @@ export const jsonLd = {
|
||||
},
|
||||
|
||||
/** Documentação técnica de framework. */
|
||||
framework(chave, framework) {
|
||||
framework(chave, framework, locale = "pt") {
|
||||
const isEn = locale === "en";
|
||||
const basePath = isEn ? `/en/frameworks/${encodeURIComponent(chave)}` : `/frameworks/${encodeURIComponent(chave)}`;
|
||||
return {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "TechArticle",
|
||||
"@id": `${SITE.url}/frameworks/${encodeURIComponent(chave)}#artigo`,
|
||||
headline: `${framework.nome} para ESP32: Guia e Documentação`,
|
||||
name: `${framework.nome_completo || framework.nome} para ESP32`,
|
||||
"@id": `${SITE.url}${basePath}#${isEn ? "article" : "artigo"}`,
|
||||
headline: isEn
|
||||
? `${framework.nome} for ESP32: Guide and Documentation`
|
||||
: `${framework.nome} para ESP32: Guia e Documentação`,
|
||||
name: isEn
|
||||
? `${framework.nome_completo || framework.nome} for ESP32`
|
||||
: `${framework.nome_completo || framework.nome} para ESP32`,
|
||||
description: framework.descricao,
|
||||
image: [`${SITE.url}/opengraph-image.png`],
|
||||
inLanguage: "pt-BR",
|
||||
inLanguage: isEn ? "en" : "pt-BR",
|
||||
datePublished: "2026-08-25T00:00:00.000Z",
|
||||
dateModified: new Date().toISOString(),
|
||||
mainEntityOfPage: `${SITE.url}/frameworks/${encodeURIComponent(chave)}`,
|
||||
url: `${SITE.url}/frameworks/${encodeURIComponent(chave)}`,
|
||||
mainEntityOfPage: `${SITE.url}${basePath}`,
|
||||
url: `${SITE.url}${basePath}`,
|
||||
author: {
|
||||
"@type": "Person",
|
||||
name: SITE.autor,
|
||||
@@ -212,25 +262,27 @@ export const jsonLd = {
|
||||
applicationCategory: "DeveloperApplication",
|
||||
operatingSystem: "Embedded",
|
||||
description: framework.descricao,
|
||||
url: framework.documentacao || `${SITE.url}/frameworks/${encodeURIComponent(chave)}`,
|
||||
url: framework.documentacao || `${SITE.url}${basePath}`,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
/** Glossário: marca cada verbete como termo definido. */
|
||||
glossario(categorias) {
|
||||
glossario(categorias, locale = "pt") {
|
||||
const isEn = locale === "en";
|
||||
const basePath = isEn ? "/en/glossary" : "/glossario";
|
||||
return {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "DefinedTermSet",
|
||||
"@id": `${SITE.url}/glossario#glossario`,
|
||||
name: "Glossário Técnico do ESP32",
|
||||
inLanguage: "pt-BR",
|
||||
"@id": `${SITE.url}${basePath}#${isEn ? "glossary" : "glossario"}`,
|
||||
name: isEn ? "ESP32 Technical Glossary" : "Glossário Técnico do ESP32",
|
||||
inLanguage: isEn ? "en" : "pt-BR",
|
||||
hasDefinedTerm: categorias.flatMap((cat) =>
|
||||
cat.termos.map((t) => ({
|
||||
"@type": "DefinedTerm",
|
||||
name: t.termo,
|
||||
description: t.definicao,
|
||||
inDefinedTermSet: `${SITE.url}/glossario#glossario`,
|
||||
inDefinedTermSet: `${SITE.url}${basePath}#${isEn ? "glossary" : "glossario"}`,
|
||||
}))
|
||||
),
|
||||
};
|
||||
@@ -250,7 +302,8 @@ export const jsonLd = {
|
||||
},
|
||||
|
||||
/** Aplicação web / ferramenta interativa (Seletor, Comparador, Catálogo). */
|
||||
aplicacaoWeb({ nome, descricao, caminho }) {
|
||||
aplicacaoWeb({ nome, descricao, caminho, locale = "pt" }) {
|
||||
const isEn = locale === "en";
|
||||
return {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebApplication",
|
||||
@@ -261,7 +314,7 @@ export const jsonLd = {
|
||||
applicationCategory: "DeveloperApplication",
|
||||
operatingSystem: "All",
|
||||
browserRequirements: "Requires JavaScript",
|
||||
inLanguage: "pt-BR",
|
||||
inLanguage: isEn ? "en" : "pt-BR",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
name: SITE.autor,
|
||||
@@ -341,15 +394,19 @@ export const jsonLd = {
|
||||
},
|
||||
|
||||
/** Página Sobre com metadados E-E-A-T de autoria e reputação. */
|
||||
paginaSobre() {
|
||||
paginaSobre(locale = "pt") {
|
||||
const isEn = locale === "en";
|
||||
const basePath = isEn ? "/en/about" : "/sobre";
|
||||
return {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "AboutPage",
|
||||
"@id": `${SITE.url}/sobre#sobre`,
|
||||
name: "Sobre o ESPDocs",
|
||||
description: "O ESPDocs é uma plataforma independente que reúne a documentação do ecossistema ESP32 em português brasileiro.",
|
||||
url: `${SITE.url}/sobre`,
|
||||
inLanguage: "pt-BR",
|
||||
"@id": `${SITE.url}${basePath}#${isEn ? "about" : "sobre"}`,
|
||||
name: isEn ? "About ESPDocs" : "Sobre o ESPDocs",
|
||||
description: isEn
|
||||
? "ESPDocs is an independent platform organizing technical documentation of the ESP32 ecosystem."
|
||||
: "O ESPDocs é uma plataforma independente que reúne a documentação do ecossistema ESP32 em português brasileiro.",
|
||||
url: `${SITE.url}${basePath}`,
|
||||
inLanguage: isEn ? "en" : "pt-BR",
|
||||
mainEntity: {
|
||||
"@type": "Person",
|
||||
name: SITE.autor,
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
{
|
||||
"Common": {
|
||||
"siteName": "ESPDocs",
|
||||
"author": "Lucas Rayan Guerra",
|
||||
"organization": "Ciência Embarcada",
|
||||
"skipToContent": "Skip to content",
|
||||
"allRightsReserved": "Content under MIT license. Made for the embedded systems community.",
|
||||
"backToHome": "Back to home",
|
||||
"explore": "Explore",
|
||||
"tools": "Tools",
|
||||
"project": "Project",
|
||||
"loading": "Loading...",
|
||||
"search": "Search...",
|
||||
"officialDocumentation": "Official documentation",
|
||||
"community": "Community",
|
||||
"mitLicense": "MIT License"
|
||||
},
|
||||
"Header": {
|
||||
"brand": "ESPDocs",
|
||||
"homeAria": "ESPDocs, homepage",
|
||||
"navAria": "Main navigation",
|
||||
"mobileNavAria": "Mobile navigation",
|
||||
"openMenu": "Open navigation menu",
|
||||
"closeMenu": "Close menu",
|
||||
"navigationTitle": "Navigation",
|
||||
"whereToGo": "Where to go",
|
||||
"selectChip": "Select chip",
|
||||
"selectMyChip": "Select my chip",
|
||||
"hardware": "Hardware",
|
||||
"hardwareDesc": "12 chips, pinouts and specifications",
|
||||
"series": "ESP32 Series",
|
||||
"seriesDesc": "12 chips, pinouts and specifications",
|
||||
"comparator": "Comparator",
|
||||
"comparatorDesc": "Up to four series side by side",
|
||||
"catalog": "Board Catalog",
|
||||
"catalogDesc": "DevKits, pinouts and where to buy",
|
||||
"tools": "Tools",
|
||||
"selector": "Smart Selector",
|
||||
"selectorDesc": "The right chip for your project",
|
||||
"diagnostics": "Diagnostics",
|
||||
"diagnosticsDesc": "Brownout, bootloop, WDT and more",
|
||||
"components": "Component Registry",
|
||||
"componentsDesc": "Drivers and idf_component.yml manifests",
|
||||
"library": "Library",
|
||||
"frameworks": "Frameworks & SDKs",
|
||||
"frameworksDesc": "ESP-IDF, Arduino, Rust and Matter",
|
||||
"glossary": "Technical Glossary",
|
||||
"glossaryDesc": "Terms appearing in datasheets",
|
||||
"about": "About the Project",
|
||||
"aboutDesc": "Authorship, method and open source"
|
||||
},
|
||||
"Footer": {
|
||||
"ariaLabel": "ESPDocs footer",
|
||||
"description": "Independent documentation of the ESP32 ecosystem. Open data, editorial curation, and links to official sources.",
|
||||
"exploreTitle": "Explore",
|
||||
"toolsTitle": "Tools",
|
||||
"projectTitle": "Project",
|
||||
"authorTitle": "Author",
|
||||
"reportIssue": "Report an issue",
|
||||
"repository": "Repository",
|
||||
"personalSite": "Personal website",
|
||||
"linkedin": "LinkedIn"
|
||||
},
|
||||
"Home": {
|
||||
"badge": "Open ESP32 documentation",
|
||||
"titleLine1": "The ESP32,",
|
||||
"titleLine2": " without noise.",
|
||||
"lede": "Specifications, pinouts, comparisons and diagnostics in a single read. Less datasheet translation, more workbench time.",
|
||||
"chooseMyChip": "Choose my chip",
|
||||
"exploreSeries": "Explore the {count} series",
|
||||
"seriesCount": "{count} series",
|
||||
"frameworkCount": "{count} frameworks",
|
||||
"portugueseFlag": "100% in English",
|
||||
"featuredSeries": "Featured series",
|
||||
"featuredDesc": "The essentials of each family before opening the datasheet.",
|
||||
"fullIndex": "Full index",
|
||||
"toolsTitle": "Start with the problem.",
|
||||
"toolsEyebrow": "Tools",
|
||||
"toolsDesc": "Tools to select the right chip, diagnose hardware errors, and accelerate development."
|
||||
},
|
||||
"NotFound": {
|
||||
"eyebrow": "Error 404",
|
||||
"title": "This page does not exist.",
|
||||
"lede": "The URL may have changed or been mistyped. Choose one of these paths to continue.",
|
||||
"backToHome": "Back to home",
|
||||
"seriesTitle": "ESP32 Series",
|
||||
"seriesDesc": "12 families, with pinouts and specifications.",
|
||||
"selectorTitle": "Chip selector",
|
||||
"selectorDesc": "Answer eight questions and find recommended models.",
|
||||
"comparatorTitle": "Comparator",
|
||||
"comparatorDesc": "Up to four series side by side.",
|
||||
"glossaryTitle": "Glossary",
|
||||
"glossaryDesc": "Hardware terms explained clearly."
|
||||
},
|
||||
"Sobre": {
|
||||
"label": "Independent project",
|
||||
"title": "About ESPDocs",
|
||||
"lede": "An unofficial platform organizing technical information about the ESP32 and linking directly to official Espressif documentation. Built for the open hardware community.",
|
||||
"viewRepository": "View repository",
|
||||
"features": {
|
||||
"portugueseTitle": "Curated Content",
|
||||
"portugueseDesc": "Structured technical data presented clearly without datasheet noise.",
|
||||
"visualCompareTitle": "Visual comparisons",
|
||||
"visualCompareDesc": "Tables and diagrams to select the right series without opening ten datasheets.",
|
||||
"centralizedAccessTitle": "Centralized access",
|
||||
"centralizedAccessDesc": "Direct links to official documentation, repositories and examples.",
|
||||
"openSourceTitle": "Open source",
|
||||
"openSourceDesc": "Contributions are welcome on Gitea."
|
||||
}
|
||||
},
|
||||
"Series": {
|
||||
"title": "ESP32 Series",
|
||||
"description": "12 ESP32 series side by side: ESP32, S2, S3, S31, C2, C3, C5, C6, C61, P4, H2 and H4. Architecture, memory, radio, peripherals and pinouts for each.",
|
||||
"pinout": "Pinout",
|
||||
"specifications": "Specifications",
|
||||
"peripherals": "Peripherals",
|
||||
"architecture": "Architecture",
|
||||
"memory": "Memory",
|
||||
"radio": "Radio",
|
||||
"security": "Hardware security"
|
||||
},
|
||||
"Catalogo": {
|
||||
"title": "Development Board Catalog",
|
||||
"description": "Official and third-party DevKits with pinouts, interfaces and purchasing links.",
|
||||
"filterBySeries": "Filter by series",
|
||||
"searchBoards": "Search boards..."
|
||||
},
|
||||
"Comparacao": {
|
||||
"title": "ESP32 Series Comparator",
|
||||
"description": "Compare up to 4 series side by side with full specifications of processing, radio, memory and pinouts."
|
||||
},
|
||||
"Componentes": {
|
||||
"title": "ESP Component Registry",
|
||||
"description": "Drivers, libraries and ready-to-use idf_component.yml manifests for ESP-IDF."
|
||||
},
|
||||
"Diagnostico": {
|
||||
"title": "Diagnostics & Troubleshooting",
|
||||
"description": "Brownout, bootloops, CPU panics, FreeRTOS and hardware best practices."
|
||||
},
|
||||
"Frameworks": {
|
||||
"title": "Frameworks & SDKs",
|
||||
"description": "Guides and overviews of main development environments: ESP-IDF, Arduino, MicroPython, Rust and ESP-Matter."
|
||||
},
|
||||
"Glossario": {
|
||||
"title": "Technical Glossary",
|
||||
"description": "Practical explanations of hardware concepts, peripherals, radio and architecture found in datasheets."
|
||||
},
|
||||
"Seletor": {
|
||||
"title": "Smart ESP32 Selector",
|
||||
"description": "Answer objective questions about your project and find the ideal series based on technical criteria."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
{
|
||||
"Common": {
|
||||
"siteName": "ESPDocs",
|
||||
"author": "Lucas Rayan Guerra",
|
||||
"organization": "Ciência Embarcada",
|
||||
"skipToContent": "Pular para o conteúdo",
|
||||
"allRightsReserved": "Conteúdo sob licença MIT. Feito para a comunidade de sistemas embarcados.",
|
||||
"backToHome": "Voltar ao início",
|
||||
"explore": "Explorar",
|
||||
"tools": "Ferramentas",
|
||||
"project": "Projeto",
|
||||
"loading": "Carregando...",
|
||||
"search": "Buscar...",
|
||||
"officialDocumentation": "Documentação oficial",
|
||||
"community": "Comunidade",
|
||||
"mitLicense": "Licença MIT"
|
||||
},
|
||||
"Header": {
|
||||
"brand": "ESPDocs",
|
||||
"homeAria": "ESPDocs, página inicial",
|
||||
"navAria": "Navegação principal",
|
||||
"mobileNavAria": "Navegação móvel",
|
||||
"openMenu": "Abrir menu de navegação",
|
||||
"closeMenu": "Fechar menu",
|
||||
"navigationTitle": "Navegação",
|
||||
"whereToGo": "Para onde ir",
|
||||
"selectChip": "Selecionar chip",
|
||||
"selectMyChip": "Selecionar meu chip",
|
||||
"hardware": "Hardware",
|
||||
"hardwareDesc": "12 chips, pinagem e especificações",
|
||||
"series": "Séries ESP32",
|
||||
"seriesDesc": "12 chips, pinagem e especificações",
|
||||
"comparator": "Comparador",
|
||||
"comparatorDesc": "Até quatro séries lado a lado",
|
||||
"catalog": "Catálogo de placas",
|
||||
"catalogDesc": "DevKits, pinos e onde comprar",
|
||||
"tools": "Ferramentas",
|
||||
"selector": "Seletor inteligente",
|
||||
"selectorDesc": "O chip certo para o seu projeto",
|
||||
"diagnostics": "Diagnóstico",
|
||||
"diagnosticsDesc": "Brownout, bootloop, WDT e mais",
|
||||
"components": "Component Registry",
|
||||
"componentsDesc": "Drivers e manifests idf_component.yml",
|
||||
"library": "Biblioteca",
|
||||
"frameworks": "Frameworks e SDKs",
|
||||
"frameworksDesc": "ESP-IDF, Arduino, Rust e Matter",
|
||||
"glossary": "Glossário técnico",
|
||||
"glossaryDesc": "Os termos que aparecem nos datasheets",
|
||||
"about": "Sobre o projeto",
|
||||
"aboutDesc": "Autoria, método e abertura",
|
||||
"book": "Livro",
|
||||
"bookNew": "Livro novo",
|
||||
"bookTitle": "Microcontroladores ESP32",
|
||||
"bookSubtitle": "Conectividade, eficiência e desempenho"
|
||||
},
|
||||
"Footer": {
|
||||
"ariaLabel": "Rodapé do ESPDocs",
|
||||
"description": "Documentação independente do ecossistema ESP32, escrita em português brasileiro. Dados públicos, curadoria editorial e links para as fontes oficiais.",
|
||||
"exploreTitle": "Explorar",
|
||||
"toolsTitle": "Ferramentas",
|
||||
"projectTitle": "Projeto",
|
||||
"authorTitle": "Autor",
|
||||
"reportIssue": "Reportar um problema",
|
||||
"repository": "Repositório",
|
||||
"personalSite": "Site pessoal",
|
||||
"linkedin": "LinkedIn",
|
||||
"bookNew": "Livro novo",
|
||||
"bookTitle": "Microcontroladores ESP32",
|
||||
"bookSubtitle": "Conectividade, eficiência e desempenho",
|
||||
"amazon": "Amazon",
|
||||
"uiclap": "UICLAP"
|
||||
},
|
||||
"Home": {
|
||||
"badge": "Documentação aberta do ESP32",
|
||||
"titleLine1": "O ESP32,",
|
||||
"titleLine2": " sem ruído.",
|
||||
"lede": "Especificações, pinagem, comparações e diagnóstico em uma leitura só. Menos tradução de datasheet, mais tempo com o protótipo na bancada.",
|
||||
"chooseMyChip": "Escolher meu chip",
|
||||
"exploreSeries": "Explorar as {count} séries",
|
||||
"seriesCount": "{count} séries",
|
||||
"frameworkCount": "{count} frameworks",
|
||||
"bookChapters": "78 capítulos no livro",
|
||||
"portugueseFlag": "100% em português",
|
||||
"featuredSeries": "Séries em destaque",
|
||||
"featuredDesc": "O essencial de cada família, antes de abrir o datasheet.",
|
||||
"fullIndex": "Índice completo",
|
||||
"toolsTitle": "Comece pelo problema.",
|
||||
"toolsEyebrow": "Ferramentas",
|
||||
"toolsDesc": "Ferramentas para selecionar o chip certo, diagnosticar erros de hardware e acelerar seu desenvolvimento.",
|
||||
"bookTitle": "Microcontroladores ESP32",
|
||||
"bookSubtitle": "Conectividade, Eficiência e Desempenho",
|
||||
"bookNewBadge": "Livro novo",
|
||||
"bookDescription": "Um percurso completo pelo hardware e pelo firmware do ESP32: da arquitetura do chip à implantação de produtos conectados. São 12 partes e 78 capítulos sobre Arduino, ESP-IDF, FreeRTOS, Wi-Fi, BLE, Thread e Matter, periféricos, depuração, baixo consumo e segurança.",
|
||||
"bookParts": "12 partes",
|
||||
"bookChaptersCount": "78 capítulos",
|
||||
"buyDigital": "Comprar digital",
|
||||
"buyPrint": "Comprar impresso",
|
||||
"fullRecord": "Ficha completa"
|
||||
},
|
||||
"NotFound": {
|
||||
"eyebrow": "Erro 404",
|
||||
"title": "Essa página não existe.",
|
||||
"lede": "O endereço pode ter mudado ou estar digitado errado. Escolha um destes caminhos para continuar.",
|
||||
"backToHome": "Voltar ao início",
|
||||
"seriesTitle": "Séries ESP32",
|
||||
"seriesDesc": "As 12 famílias, com pinagem e especificações.",
|
||||
"selectorTitle": "Seletor de chip",
|
||||
"selectorDesc": "Responda a oito perguntas e receba os modelos indicados.",
|
||||
"comparatorTitle": "Comparador",
|
||||
"comparatorDesc": "Até quatro séries lado a lado.",
|
||||
"glossaryTitle": "Glossário",
|
||||
"glossaryDesc": "Termos de hardware explicados em português."
|
||||
},
|
||||
"Sobre": {
|
||||
"label": "Projeto independente",
|
||||
"title": "Sobre o ESPDocs",
|
||||
"lede": "Uma plataforma não oficial, em português, que organiza as informações técnicas do ESP32 e leva você à documentação oficial da Espressif. Feita para a comunidade de hardware livre.",
|
||||
"viewRepository": "Ver o repositório",
|
||||
"features": {
|
||||
"portugueseTitle": "Em português",
|
||||
"portugueseDesc": "Dados técnicos organizados e apresentados em português do Brasil.",
|
||||
"visualCompareTitle": "Comparações visuais",
|
||||
"visualCompareDesc": "Tabelas e diagramas para escolher a série certa sem abrir dez datasheets.",
|
||||
"centralizedAccessTitle": "Acesso centralizado",
|
||||
"centralizedAccessDesc": "Links diretos para a documentação oficial, repositórios e exemplos.",
|
||||
"openSourceTitle": "Código aberto",
|
||||
"openSourceDesc": "Contribuições são bem-vindas no Gitea."
|
||||
}
|
||||
},
|
||||
"Series": {
|
||||
"title": "Séries ESP32",
|
||||
"description": "As 12 séries de ESP32 lado a lado: ESP32, S2, S3, S31, C2, C3, C5, C6, C61, P4, H2 e H4. Arquitetura, memória, rádio, periféricos e pinagem de cada uma, em português.",
|
||||
"pinout": "Pinagem",
|
||||
"specifications": "Especificações",
|
||||
"peripherals": "Periféricos",
|
||||
"architecture": "Arquitetura",
|
||||
"memory": "Memória",
|
||||
"radio": "Rádio",
|
||||
"security": "Segurança em hardware"
|
||||
},
|
||||
"Catalogo": {
|
||||
"title": "Catálogo de Placas de Desenvolvimento",
|
||||
"description": "DevKits oficiais e de terceiros com pinagem, interfaces e links para compra.",
|
||||
"filterBySeries": "Filtrar por série",
|
||||
"searchBoards": "Buscar placas..."
|
||||
},
|
||||
"Comparacao": {
|
||||
"title": "Comparador de Séries ESP32",
|
||||
"description": "Compare até 4 séries lado a lado com especificações completas de processamento, rádio, memória e pinagem."
|
||||
},
|
||||
"Componentes": {
|
||||
"title": "ESP Component Registry",
|
||||
"description": "Drivers, bibliotecas e manifests idf_component.yml prontos para uso no ESP-IDF."
|
||||
},
|
||||
"Diagnostico": {
|
||||
"title": "Diagnóstico & Resolução de Problemas",
|
||||
"description": "Brownout, bootloops, pânicos de CPU, FreeRTOS e boas práticas de hardware."
|
||||
},
|
||||
"Frameworks": {
|
||||
"title": "Frameworks e SDKs",
|
||||
"description": "Guias e visão geral dos principais ambientes de desenvolvimento: ESP-IDF, Arduino, MicroPython, Rust e ESP-Matter."
|
||||
},
|
||||
"Glossario": {
|
||||
"title": "Glossário Técnico",
|
||||
"description": "Explicações práticas em português de conceitos de hardware, periféricos, rádio e arquitetura que aparecem nos datasheets."
|
||||
},
|
||||
"Seletor": {
|
||||
"title": "Seletor Inteligente de ESP32",
|
||||
"description": "Responda a perguntas objetivas sobre o seu projeto e descubra a série ideal com base técnica."
|
||||
},
|
||||
"Livro": {
|
||||
"title": "Microcontroladores ESP32, o livro",
|
||||
"subtitle": "Conectividade, eficiência e desempenho",
|
||||
"badge": "Livro novo · 1ª edição",
|
||||
"description": "12 partes e 78 capítulos em português cobrindo o ecossistema ESP32 do hardware ao firmware.",
|
||||
"buyDigital": "Comprar digital",
|
||||
"buyPrint": "Comprar impresso",
|
||||
"chaptersTitle": "Conteúdo e Capítulos"
|
||||
}
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
import createMiddleware from "next-intl/middleware";
|
||||
import { NextResponse } from "next/server";
|
||||
import { routing } from "./i18n/routing";
|
||||
import { ALL_LOCALE_CODES, ENABLED_LOCALES, getLocalizedHref } from "./i18n/links";
|
||||
|
||||
const intlMiddleware = createMiddleware(routing);
|
||||
|
||||
function parseAcceptLanguage(header) {
|
||||
if (!header) return [];
|
||||
return header
|
||||
.split(",")
|
||||
.map((part) => {
|
||||
const [langRange, qPart] = part.trim().split(";");
|
||||
let q = 1.0;
|
||||
if (qPart) {
|
||||
const match = qPart.match(/q=([\d.]+)/);
|
||||
if (match) {
|
||||
const parsed = parseFloat(match[1]);
|
||||
if (!isNaN(parsed)) q = parsed;
|
||||
}
|
||||
}
|
||||
return { lang: langRange.trim().toLowerCase(), q };
|
||||
})
|
||||
.sort((a, b) => b.q - a.q);
|
||||
}
|
||||
|
||||
function matchLocale(lang) {
|
||||
if (lang.startsWith("pt")) return "pt";
|
||||
if (lang.startsWith("es")) return "es";
|
||||
if (lang.startsWith("fr")) return "fr";
|
||||
if (lang.startsWith("de")) return "de";
|
||||
if (lang.startsWith("zh")) return "zh-CN";
|
||||
if (lang.startsWith("en")) return "en";
|
||||
return null;
|
||||
}
|
||||
|
||||
function resolveRootLocale(request) {
|
||||
const cookieValue = request.cookies.get("NEXT_LOCALE")?.value;
|
||||
if (cookieValue && ENABLED_LOCALES.includes(cookieValue)) {
|
||||
return cookieValue;
|
||||
}
|
||||
const acceptLang = request.headers.get("accept-language");
|
||||
const parsed = parseAcceptLanguage(acceptLang);
|
||||
for (const { lang } of parsed) {
|
||||
const matched = matchLocale(lang);
|
||||
if (matched && ENABLED_LOCALES.includes(matched)) {
|
||||
return matched;
|
||||
}
|
||||
}
|
||||
return ENABLED_LOCALES.includes("en") ? "en" : (ENABLED_LOCALES[0] || "pt");
|
||||
}
|
||||
|
||||
export default function middleware(request) {
|
||||
const { pathname, search } = request.nextUrl;
|
||||
|
||||
// Exclusões de caminhos e arquivos estáticos
|
||||
if (
|
||||
pathname.startsWith("/api") ||
|
||||
pathname.startsWith("/_next") ||
|
||||
pathname === "/robots.txt" ||
|
||||
pathname === "/sitemap.xml" ||
|
||||
pathname === "/google21a790a2c23c0ec5.html" ||
|
||||
/\.[a-zA-Z0-9]+$/.test(pathname)
|
||||
) {
|
||||
return NextResponse.next();
|
||||
}
|
||||
|
||||
// 1. Raiz: negociação de idioma (307) considerando apenas idiomas ATIVOS
|
||||
if (pathname === "/") {
|
||||
const targetLocale = resolveRootLocale(request);
|
||||
const url = new URL(`/${targetLocale}`, request.url);
|
||||
url.search = search;
|
||||
const response = NextResponse.redirect(url, 307);
|
||||
response.headers.set("Vary", "Accept-Language, Cookie");
|
||||
response.headers.set("Cache-Control", "private, no-store");
|
||||
return response;
|
||||
}
|
||||
|
||||
// 2. Idiomas INATIVOS: prefixos (/es, /fr, /de, /zh-CN etc.)
|
||||
// Redirecionam com 307 para o mesmo caminho no idioma fallback (en se ativo, senão pt) quando o slug existir lá.
|
||||
const inactiveLocales = ALL_LOCALE_CODES.filter((l) => !ENABLED_LOCALES.includes(l));
|
||||
if (inactiveLocales.length > 0) {
|
||||
const isInactive = inactiveLocales.some(
|
||||
(loc) => pathname === `/${loc}` || pathname.startsWith(`/${loc}/`)
|
||||
);
|
||||
if (isInactive) {
|
||||
const fallbackLocale = ENABLED_LOCALES.includes("en") ? "en" : "pt";
|
||||
const targetPath = getLocalizedHref(pathname, fallbackLocale);
|
||||
const url = new URL(targetPath, request.url);
|
||||
if (search && !targetPath.includes("?")) {
|
||||
url.search = search;
|
||||
}
|
||||
return NextResponse.redirect(url, 307);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Livro fora do português para idiomas ATIVOS que não são pt: 404
|
||||
const activeNonPt = ENABLED_LOCALES.filter((l) => l !== "pt");
|
||||
if (activeNonPt.length > 0) {
|
||||
const isBookInOtherActiveLocale = activeNonPt.some(
|
||||
(loc) => pathname === `/${loc}/livro` || pathname.startsWith(`/${loc}/livro/`)
|
||||
);
|
||||
if (isBookInOtherActiveLocale) {
|
||||
return new NextResponse(null, { status: 404 });
|
||||
}
|
||||
}
|
||||
|
||||
// 4. URLs antigas sem prefixo reconhecido: redirecionamento 308 para /pt/<caminho>
|
||||
const hasActivePrefix = ENABLED_LOCALES.some(
|
||||
(loc) => pathname === `/${loc}` || pathname.startsWith(`/${loc}/`)
|
||||
);
|
||||
|
||||
if (!hasActivePrefix) {
|
||||
const url = new URL(`/pt${pathname}`, request.url);
|
||||
url.search = search;
|
||||
return NextResponse.redirect(url, 308);
|
||||
}
|
||||
|
||||
// 5. Delegação para o roteamento do next-intl para idiomas ativos
|
||||
return intlMiddleware(request);
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: [
|
||||
"/((?!api|_next|_vercel|.*\\..*|robots\\.txt|sitemap\\.xml|google21a790a2c23c0ec5\\.html).*)",
|
||||
],
|
||||
};
|
||||
+10
-1
@@ -1,8 +1,16 @@
|
||||
import createNextIntlPlugin from "next-intl/plugin";
|
||||
|
||||
const withNextIntl = createNextIntlPlugin("./i18n/request.js");
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
// A imagem Docker liga isto (NEXT_OUTPUT=standalone) para empacotar só o que
|
||||
// o servidor usa. Fora dela o build continua igual: `next start`/pm2.
|
||||
output: process.env.NEXT_OUTPUT === "standalone" ? "standalone" : undefined,
|
||||
// Metadata (title, canonical, hreflang, Open Graph) sempre no <head> do HTML
|
||||
// inicial, para qualquer cliente. Sem isso o Next 15.5 a transmite no <body>
|
||||
// para navegadores e Googlebot, e só os robôs de preview a recebem no <head>.
|
||||
htmlLimitedBots: /.*/,
|
||||
experimental: {
|
||||
optimizePackageImports: [
|
||||
"lucide-react",
|
||||
@@ -13,4 +21,5 @@ const nextConfig = {
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
export default withNextIntl(nextConfig);
|
||||
|
||||
Generated
+754
-3
@@ -11,6 +11,7 @@
|
||||
"googleapis": "^165.0.0",
|
||||
"lucide-react": "^1.16.0",
|
||||
"next": "^15.5.28",
|
||||
"next-intl": "^4.14.9",
|
||||
"next-themes": "^0.4.6",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0"
|
||||
@@ -37,6 +38,31 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@eloqnt/config": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@eloqnt/config/-/config-0.1.1.tgz",
|
||||
"integrity": "sha512-YRDigSaiJEzKDfzTth5kG+L/PKfB3mo8h7yNzpXExPfvQmcD05WoZT57PdhJE0jI+Vva6eb0OCU8hnHHgdME3g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@eloqnt/format-json": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@eloqnt/format-json/-/format-json-0.1.0.tgz",
|
||||
"integrity": "sha512-4Pkb+HyzgWNJXoU48aJhUyNZSjZvMGooPCNG1ZFmBm55xTiNNPQCNXH66Ob6sXS6RvbWZrRpCf+Uo/Jz9K9g+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eloqnt/config": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eloqnt/format-po": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@eloqnt/format-po/-/format-po-0.1.1.tgz",
|
||||
"integrity": "sha512-aLtmIoqXGEaeTT0RcsLN8sZ3aIrsT/c/dVs28zrLhDjO3+vA3KNP+r98N0xq8w/k36+/GIUt4uZNbqcA71GVWw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eloqnt/config": "^0.1.1",
|
||||
"po-parser": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
|
||||
@@ -214,6 +240,36 @@
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/fast-memoize": {
|
||||
"version": "3.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.7.tgz",
|
||||
"integrity": "sha512-zXfhLpvA6T7+efdt9JLbBwZ00tT7NsBMDVnDu8rpHeNNv8KfRZAMo2gkG0k9lK/Nzc//3kJ9pImsfuJxk3KhUA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@formatjs/icu-messageformat-parser": {
|
||||
"version": "3.5.22",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.22.tgz",
|
||||
"integrity": "sha512-YuwN+dDKgssfuYwtOyGQD0CSn7K46g9cv1Fp0VgKpjZDDFvv8b8crzP990IcJhRPWHhKzCGsbUSJVIguyyFA5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@formatjs/icu-skeleton-parser": "2.1.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/icu-skeleton-parser": {
|
||||
"version": "2.1.12",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.12.tgz",
|
||||
"integrity": "sha512-ca7tZMLpfHX3sUD7hP6gE/qr6Iq89EDd3ZLeRhbsB7r0UD55DGJq+tmFLzrGrnx5StahUevQmQQVtbDRHsfDHA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@formatjs/intl-localematcher": {
|
||||
"version": "0.8.14",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.8.14.tgz",
|
||||
"integrity": "sha512-8O7V38QmbB11+ryJ3KM/znrzXtiqgpXzqNoqDsndHZZ5/zDKTTL+cf5F0mzXkQEwhx8IlWnqYvEovf2S5EwLTw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@formatjs/fast-memoize": "3.1.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanfs/core": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz",
|
||||
@@ -1108,6 +1164,292 @@
|
||||
"node": ">=12.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.6.0.tgz",
|
||||
"integrity": "sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"detect-libc": "^2.0.3",
|
||||
"is-glob": "^4.0.3",
|
||||
"node-addon-api": "^7.0.0",
|
||||
"picomatch": "^4.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@parcel/watcher-android-arm64": "2.6.0",
|
||||
"@parcel/watcher-darwin-arm64": "2.6.0",
|
||||
"@parcel/watcher-darwin-x64": "2.6.0",
|
||||
"@parcel/watcher-freebsd-x64": "2.6.0",
|
||||
"@parcel/watcher-linux-arm-glibc": "2.6.0",
|
||||
"@parcel/watcher-linux-arm-musl": "2.6.0",
|
||||
"@parcel/watcher-linux-arm64-glibc": "2.6.0",
|
||||
"@parcel/watcher-linux-arm64-musl": "2.6.0",
|
||||
"@parcel/watcher-linux-x64-glibc": "2.6.0",
|
||||
"@parcel/watcher-linux-x64-musl": "2.6.0",
|
||||
"@parcel/watcher-win32-arm64": "2.6.0",
|
||||
"@parcel/watcher-win32-x64": "2.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-android-arm64": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.6.0.tgz",
|
||||
"integrity": "sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-darwin-arm64": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.6.0.tgz",
|
||||
"integrity": "sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-darwin-x64": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.6.0.tgz",
|
||||
"integrity": "sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-freebsd-x64": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.6.0.tgz",
|
||||
"integrity": "sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-arm-glibc": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.6.0.tgz",
|
||||
"integrity": "sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-arm-musl": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.6.0.tgz",
|
||||
"integrity": "sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-arm64-glibc": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.6.0.tgz",
|
||||
"integrity": "sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-arm64-musl": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.6.0.tgz",
|
||||
"integrity": "sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-x64-glibc": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.6.0.tgz",
|
||||
"integrity": "sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-linux-x64-musl": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.6.0.tgz",
|
||||
"integrity": "sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-win32-arm64": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.6.0.tgz",
|
||||
"integrity": "sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher-win32-x64": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.6.0.tgz",
|
||||
"integrity": "sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/@parcel/watcher/node_modules/picomatch": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
|
||||
"integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
@@ -1161,6 +1503,210 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@schummar/icu-type-parser": {
|
||||
"version": "1.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@schummar/icu-type-parser/-/icu-type-parser-1.21.5.tgz",
|
||||
"integrity": "sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@swc/core-darwin-arm64": {
|
||||
"version": "1.16.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.16.21.tgz",
|
||||
"integrity": "sha512-VRreJpbRygpSD1hj3HBEOIA1xjXYnhB+IfcKsxZRhCIBGRP4UkqxZH4/ipFh/heIRp7EKQ56E8ygwEftLNCWXw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-darwin-x64": {
|
||||
"version": "1.16.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.16.21.tgz",
|
||||
"integrity": "sha512-KqCJ04pMYDBUYpAOFGUFR8TEjqo4h0Vtwe/za9xNRDKsxSDnjgM7HVhfO0uNNpMMlM2ao2E6d0iLpApIRvNGnA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm-gnueabihf": {
|
||||
"version": "1.16.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.16.21.tgz",
|
||||
"integrity": "sha512-tLkw3uWxQj69qBRX5Xm8vbq+5iX5e/ktoPXhrDeFFa2jNMc+AWcxa0bqwatvVGK40v5mcmz6Ulu5Nk9jF8ciMA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm64-gnu": {
|
||||
"version": "1.16.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.16.21.tgz",
|
||||
"integrity": "sha512-lFHVlHB0B5C7FwyprWJQp7b2iF/ohj2RqnMiv8uCnFJc+rYP0Py2I7ftZ+rOX4Zu7Ra9eMk7GnmuxAywCZYUJQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm64-musl": {
|
||||
"version": "1.16.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.16.21.tgz",
|
||||
"integrity": "sha512-gXDgrMMDsWT7r5gZsml10snBS9yaoVYwU9vGffa+DAts4ctEMrMHv+G8AH+ZxCV9gr5MfdgtGGQKjXjLay4mXQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-ppc64-gnu": {
|
||||
"version": "1.16.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.16.21.tgz",
|
||||
"integrity": "sha512-hZF7J2YzXiADZ4eQxTFOWJcSSy3fbUR8/DcCXqiBHh0bVyLl2Y+O5pVWxk/r/XV5tA9n7DnnLlvkPPsHoajE9w==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-s390x-gnu": {
|
||||
"version": "1.16.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.16.21.tgz",
|
||||
"integrity": "sha512-rmtGwkAlbl+fQMGrGUMklUmByueOmt1ju9sKsE5YWVA0KfFYM0W87WVx4lFYQXt+E4P3zkLjeqo/AUa5mFbF1A==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-x64-gnu": {
|
||||
"version": "1.16.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.16.21.tgz",
|
||||
"integrity": "sha512-EUJsyrFw3aNE64iQzk3bDqjADgl4l0vpxfwVMjMuZIooNg35yKqvkw3bYNEhQyrBDY0+5kKoiirGLpth3Wf3lA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-x64-musl": {
|
||||
"version": "1.16.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.16.21.tgz",
|
||||
"integrity": "sha512-ZXUnLjxTHxvNhVmQmYlb8XNKArfi/MiGoW5DmfuME8ttCLH9OJTqJVFy7g1yYxUCgw3tU6dF1uU59N8P/Yr5Pw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-arm64-msvc": {
|
||||
"version": "1.16.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.16.21.tgz",
|
||||
"integrity": "sha512-jnnQpAHiWZgEobVfOPvJJzm1Jh4ZEIKh2IqcDqHv6zJcjvaEkHdkt+qdRsJ9AqvK7g18WBRHTnvKm5IxdbkagA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-ia32-msvc": {
|
||||
"version": "1.16.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.16.21.tgz",
|
||||
"integrity": "sha512-TaVTnNm9c1I+VG3hJUt11uspwbTrTQ9+fUPzODlvx4tj/ChYqUm4cKTIHw3O97hILxpmhBR0hbvLEs9seOV59A==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-x64-msvc": {
|
||||
"version": "1.16.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.16.21.tgz",
|
||||
"integrity": "sha512-aPv58Clf6SdAQtouzDYKbEtcCETY2hOXlrHgSFnFIJQOlMWINHSGazaM1Iv63/9wOUDPq6+0ZFytMqnPtER9OQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/counter": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
|
||||
"integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@swc/helpers": {
|
||||
"version": "0.5.15",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
|
||||
@@ -1170,6 +1716,15 @@
|
||||
"tslib": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/types": {
|
||||
"version": "0.1.28",
|
||||
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.28.tgz",
|
||||
"integrity": "sha512-V6Mnml8v09QALx6K0elJ7o9K/MkVDtW3t6L+7Ou/JcWtb3xwId2AH4FeOceySd2JaO87IMw4+6vSZxLm34LPbw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@swc/counter": "^0.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/node": {
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz",
|
||||
@@ -2699,6 +3254,19 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/content-type": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
|
||||
"integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
@@ -2847,7 +3415,6 @@
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -4233,6 +4800,21 @@
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/icu-minify": {
|
||||
"version": "4.14.9",
|
||||
"resolved": "https://registry.npmjs.org/icu-minify/-/icu-minify-4.14.9.tgz",
|
||||
"integrity": "sha512-PmO+fNnC3K3mfPKTnm3RrPERrhQZnjm1AlpyZQ0ShbXi8Y/kYZ3YOde8TEjCLz9k3P2DmzkBn8lykGrCAi1Ajw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/amannn"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@formatjs/icu-messageformat-parser": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||
@@ -4285,6 +4867,31 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/intl-messageformat": {
|
||||
"version": "11.2.15",
|
||||
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-11.2.15.tgz",
|
||||
"integrity": "sha512-W4VNytsXyWgW5lvVchmsb9xgA5rSKqoflu3/IQ9UCtB0z4R+Bx9MoEkwFT/+30RCl/KzUoH0QGGe9lppF5SuvQ==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@formatjs/fast-memoize": "3.1.7",
|
||||
"@formatjs/icu-messageformat-parser": "3.5.18"
|
||||
}
|
||||
},
|
||||
"node_modules/intl-messageformat/node_modules/@formatjs/icu-messageformat-parser": {
|
||||
"version": "3.5.18",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.18.tgz",
|
||||
"integrity": "sha512-wX1efcL8d7K5QapOTRsP/OLTA/kpwe4LwqWyNxDNg5iRs8i9jJbCyxB5P8jc4KOW5oiLzz2DJr+BRY5xMV9+bA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@formatjs/icu-skeleton-parser": "2.1.11"
|
||||
}
|
||||
},
|
||||
"node_modules/intl-messageformat/node_modules/@formatjs/icu-skeleton-parser": {
|
||||
"version": "2.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.11.tgz",
|
||||
"integrity": "sha512-j8cUmOJzVgkHuS0QiQ6ga76UIoLOFSAMWhs7aZJztH3aAdCOAE6vpC8KVvFB4cU10ON0y2/5oOVmPJ43s2lTwA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-array-buffer": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
|
||||
@@ -4450,7 +5057,6 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -4505,7 +5111,6 @@
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
@@ -5386,6 +5991,22 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.1.0.tgz",
|
||||
"integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"content-type": "^2.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/next": {
|
||||
"version": "15.5.28",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-15.5.28.tgz",
|
||||
@@ -5438,6 +6059,97 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/next-intl": {
|
||||
"version": "4.14.9",
|
||||
"resolved": "https://registry.npmjs.org/next-intl/-/next-intl-4.14.9.tgz",
|
||||
"integrity": "sha512-uauRtUC+TrYNA1OL/QcwL9irndLrI9jK3Wdaa9W0B5AeKh9cqVdNeT0IWgLnhBqBRrVwppVdI0M+C1+JdGPQ3w==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/amannn"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eloqnt/config": "^0.1.1",
|
||||
"@eloqnt/format-json": "^0.1.0",
|
||||
"@eloqnt/format-po": "^0.1.1",
|
||||
"@formatjs/intl-localematcher": "^0.8.1",
|
||||
"@parcel/watcher": "^2.4.1",
|
||||
"@swc/core": "~1.16.0",
|
||||
"icu-minify": "^4.14.9",
|
||||
"negotiator": "^1.0.0",
|
||||
"next-intl-swc-plugin-extractor": "4.14.9",
|
||||
"use-intl": "^4.14.9"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/next-intl-swc-plugin-extractor": {
|
||||
"version": "4.14.9",
|
||||
"resolved": "https://registry.npmjs.org/next-intl-swc-plugin-extractor/-/next-intl-swc-plugin-extractor-4.14.9.tgz",
|
||||
"integrity": "sha512-8jAkmDwQJo6RDavBHm9QRl1YTn2WXf+rI4SVhMaZxZcxopnwZic6fKTXOoNIo3kzC+a6vJySkOkXmHTVFLAYtg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/next-intl/node_modules/@swc/core": {
|
||||
"version": "1.16.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.16.21.tgz",
|
||||
"integrity": "sha512-sE2asan0US6gcp11oBDFJb5+s+ltaAPBcagVQGub1+qo+8TsQET2TmXfJCw/Oy0w1eEPp1rV1wsR/Umx2KXGcw==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@swc/counter": "^0.1.3",
|
||||
"@swc/types": "^0.1.28"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/swc"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@swc/core-darwin-arm64": "1.16.21",
|
||||
"@swc/core-darwin-x64": "1.16.21",
|
||||
"@swc/core-linux-arm-gnueabihf": "1.16.21",
|
||||
"@swc/core-linux-arm64-gnu": "1.16.21",
|
||||
"@swc/core-linux-arm64-musl": "1.16.21",
|
||||
"@swc/core-linux-ppc64-gnu": "1.16.21",
|
||||
"@swc/core-linux-s390x-gnu": "1.16.21",
|
||||
"@swc/core-linux-x64-gnu": "1.16.21",
|
||||
"@swc/core-linux-x64-musl": "1.16.21",
|
||||
"@swc/core-win32-arm64-msvc": "1.16.21",
|
||||
"@swc/core-win32-ia32-msvc": "1.16.21",
|
||||
"@swc/core-win32-x64-msvc": "1.16.21"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/helpers": ">=0.5.17"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@swc/helpers": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/next-intl/node_modules/@swc/helpers": {
|
||||
"version": "0.5.23",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz",
|
||||
"integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==",
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/next-themes": {
|
||||
"version": "0.4.6",
|
||||
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz",
|
||||
@@ -5448,6 +6160,12 @@
|
||||
"react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc"
|
||||
}
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
|
||||
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/node-domexception": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
||||
@@ -5786,6 +6504,12 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/po-parser": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/po-parser/-/po-parser-2.2.0.tgz",
|
||||
"integrity": "sha512-NdTrKgh0oO7+y+RFX8KKhOB438x/j94UGXEFzl/7pHH0JjWSn42iJ9tgmPksIO6n1JKDHmNDcejPJfKspljB9g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/possible-typed-array-names": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
|
||||
@@ -7009,6 +7733,33 @@
|
||||
"integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==",
|
||||
"license": "BSD"
|
||||
},
|
||||
"node_modules/use-intl": {
|
||||
"version": "4.14.9",
|
||||
"resolved": "https://registry.npmjs.org/use-intl/-/use-intl-4.14.9.tgz",
|
||||
"integrity": "sha512-37ktvdCCz+6JY2VFPl/GV69Ds4ahiUT2c2xEZZRZYxdgGLxFsUbdxzjQVRm3YMIOUU0VPs6zvlifb4Yjk4IxIg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/amannn"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@formatjs/fast-memoize": "^3.1.0",
|
||||
"@schummar/icu-type-parser": "1.21.5",
|
||||
"icu-minify": "^4.14.9",
|
||||
"intl-messageformat": "^11.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react": "^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/web-streams-polyfill": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
|
||||
|
||||
Loaded 100 of 119 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user