Compare commits
12
Commits
fb59015fca
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b673aeb4b | ||
|
|
660b28c09d | ||
|
|
0940814522 | ||
|
|
0d5f8f9c5f | ||
|
|
47c55515bb | ||
|
|
c1bd2c7e11 | ||
|
|
22b1f26aed | ||
|
|
d479a8d361 | ||
|
|
3a1a095e97 | ||
|
|
cbf724db2a | ||
|
|
dcd4ef7e1b | ||
|
|
02dee65b2b |
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>
|
||||
|
||||
+62
-1
@@ -6,6 +6,44 @@ Tudo o que muda de relevante no ESPDocs está aqui. O formato segue o
|
||||
|
||||
## [Não lançado]
|
||||
|
||||
## [1.4.0] - 2026-11-01
|
||||
|
||||
### Adicionado
|
||||
|
||||
- Internacionalização completa para o idioma espanhol neutro latino-americano (`es`) (Fase 4):
|
||||
- Ativação do espanhol em `ENABLED_LOCALES = ["pt", "en", "es"]` e no seletor de idiomas do cabeçalho.
|
||||
- Tradução técnica integral e paridade estrutural em `messages/es.json` (15 namespaces) e arquivos de dados em `data/es/` (`series.json`, `frameworks.json`, `conexoes/*.json`) e `lib/data/es/` (`glossario.js`, `diagnostico.js`, `componentes.js`, `topicos.js`).
|
||||
- 14 exemplos práticos de código com comentários em espanhol em `public/exemplos/es/`.
|
||||
- Roteamento com slugs canônicos em espanhol (`/es/catalogo`, `/es/comparacion`, `/es/componentes`, `/es/diagnostico`, `/es/frameworks`, `/es/glosario`, `/es/selector`, `/es/acerca`).
|
||||
- Busca por idioma em `/api/busca/es` com normalização de acentos e 'ñ', sem menção ao livro e com links para os slugs canônicos em espanhol.
|
||||
- Exclusão total e estrita de referências ao livro no idioma espanhol (menu, rodapé, busca, sitemap e metadados), mantendo `/es/livro` respondendo HTTP 404.
|
||||
- Tabela de catálogo com cabeçalhos traduzidos e mapeamento de valores na interface em espanhol.
|
||||
- Negociação de idioma na raiz com roteamento para `es` para cabeçalhos Accept-Language `es-*` ou cookie `NEXT_LOCALE=es`, e fallback padrão para `en` para navegadores com idiomas inativos (`fr`, `de`, `zh-CN`).
|
||||
- Metadados de SEO, Open Graph e Twitter Cards localizados com `og:locale` (`es_419`), `inLanguage` (`es-419`) e `hreflang` cruzado entre `pt-BR`, `en`, `es-419` e `x-default`.
|
||||
- Extensão dos scripts de verificação: `scripts/check-i18n.mjs` valida `es`, `scripts/smoke-imagem.sh` testa as rotas espanholas e `scripts/verifica-vazamentos.py` varre as 36 rotas em espanhol (texto visível e JSON-LD).
|
||||
|
||||
## [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):
|
||||
@@ -17,6 +55,26 @@ Tudo o que muda de relevante no ESPDocs está aqui. O formato segue o
|
||||
- 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
|
||||
|
||||
@@ -92,6 +150,9 @@ 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.1.0...HEAD
|
||||
[Não lançado]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/compare/v1.4.0...HEAD
|
||||
[1.4.0]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/compare/v1.3.0...v1.4.0
|
||||
[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
|
||||
@@ -1,13 +1,32 @@
|
||||
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 async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
return paginaMeta({
|
||||
titulo: isEn ? "ESP32 Board Catalog" : isEs ? "Catálogo de placas ESP32" : "Catálogo de placas ESP32",
|
||||
descricao: isEn
|
||||
? "ESP32 development boards and DevKits available in Brazil, with filters by series, connector, and USB-serial converter."
|
||||
: isEs
|
||||
? "Placas de desarrollo y DevKits con ESP32, con filtros por serie, conector y conversor USB-serial."
|
||||
: "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"]
|
||||
: isEs
|
||||
? ["placas ESP32", "DevKit ESP32", "comprar 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";
|
||||
const isEs = locale === "es";
|
||||
const canonPath = isEn ? "/en/catalog" : isEs ? "/es/catalogo" : "/catalogo";
|
||||
|
||||
export default function Layout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
@@ -15,9 +34,14 @@ export default function Layout({ children }) {
|
||||
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",
|
||||
nome: isEn ? "ESP32 Development Board Catalog" : isEs ? "Catálogo de placas de desarrollo ESP32" : "Catálogo de Placas ESP32",
|
||||
descricao: isEn
|
||||
? "Interactive guide and catalog of development boards and DevKits featuring ESP32 microcontrollers."
|
||||
: isEs
|
||||
? "Guía y catálogo interactivo de placas de desarrollo y DevKits con microcontroladores ESP32."
|
||||
: "Guia e catálogo interativo de placas de desenvolvimento e DevKits com microcontroladores ESP32.",
|
||||
caminho: canonPath,
|
||||
locale,
|
||||
})
|
||||
),
|
||||
}}
|
||||
@@ -27,8 +51,8 @@ export default function Layout({ children }) {
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Catálogo de Placas", caminho: "/catalogo" },
|
||||
{ nome: isEn ? "Home" : isEs ? "Inicio" : "Início", caminho: isEn ? "/en" : isEs ? "/es" : "/" },
|
||||
{ nome: isEn ? "Board Catalog" : isEs ? "Catálogo de placas" : "Catálogo de Placas", caminho: canonPath },
|
||||
])
|
||||
),
|
||||
}}
|
||||
|
||||
+146
-60
@@ -1,29 +1,83 @@
|
||||
"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",
|
||||
};
|
||||
|
||||
const HEADER_MAP_ES = {
|
||||
"Nome": "Nombre",
|
||||
"Descrição": "Descripción",
|
||||
"Série": "Serie",
|
||||
"Loja Oficial": "Tienda oficial",
|
||||
"Fabricante": "Fabricante",
|
||||
"Processador": "Procesador",
|
||||
"Memória Flash": "Memoria flash",
|
||||
"PSRAM": "PSRAM",
|
||||
"Conector USB": "Conector USB",
|
||||
"Interface USB": "Interfaz USB",
|
||||
"Antena": "Antena",
|
||||
"Bateria": "Batería",
|
||||
"Display": "Pantalla",
|
||||
"Sensores": "Sensores",
|
||||
"Botões": "Botones",
|
||||
"LEDs": "LEDs",
|
||||
};
|
||||
|
||||
const VALUE_MAP_ES = {
|
||||
"Sim": "Sí",
|
||||
"Não": "No",
|
||||
"Opcional": "Opcional",
|
||||
};
|
||||
|
||||
export default function PlacasPage() {
|
||||
const pathname = usePathname() || "";
|
||||
const isEn = pathname === "/en" || pathname.startsWith("/en/");
|
||||
const isEs = pathname === "/es" || pathname.startsWith("/es/");
|
||||
|
||||
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,10 +87,10 @@ 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" : isEs ? "Error al cargar los datos de las placas" : "Erro ao carregar dados das placas");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
@@ -54,11 +108,11 @@ 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());
|
||||
@@ -66,14 +120,12 @@ export default function PlacasPage() {
|
||||
});
|
||||
|
||||
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 +136,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 +145,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,7 +161,7 @@ export default function PlacasPage() {
|
||||
};
|
||||
|
||||
const handleFilterToggle = (column, value) => {
|
||||
setActiveFilters(prev => {
|
||||
setActiveFilters((prev) => {
|
||||
const newFilters = { ...prev };
|
||||
|
||||
if (!newFilters[column]) {
|
||||
@@ -120,13 +169,11 @@ export default function PlacasPage() {
|
||||
} 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 +184,7 @@ export default function PlacasPage() {
|
||||
|
||||
const clearFilters = () => {
|
||||
setActiveFilters({});
|
||||
setSearchTerm('');
|
||||
setSearchTerm("");
|
||||
};
|
||||
|
||||
const activeFilterCount = Object.keys(activeFilters).length + (searchTerm ? 1 : 0);
|
||||
@@ -146,11 +193,19 @@ export default function PlacasPage() {
|
||||
|
||||
const hero = (
|
||||
<PageHero
|
||||
trail={[{ label: "Catálogo de placas" }]}
|
||||
isEn={isEn}
|
||||
isEs={isEs}
|
||||
trail={[{ label: isEn ? "Board Catalog" : isEs ? "Catálogo de placas" : "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" : isEs ? "DevKits y módulos reales" : "DevKits e módulos reais"}
|
||||
title={isEn ? "ESP32 Board Catalog" : isEs ? "Catálogo de placas ESP32" : "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."
|
||||
: isEs
|
||||
? "Compare placas oficiales y alternativas para su proyecto: interfaz USB, sensores integrados y enlace directo a la tienda."
|
||||
: "Compare placas oficiais e alternativas para o seu projeto: interface USB, sensores integrados e link direto para a loja."
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -160,13 +215,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" : isEs ? "Cargando placas" : "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…" : isEs ? "Consultando la base de datos de placas…" : "Consultando o banco de placas…"}
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
<Footer />
|
||||
@@ -184,11 +241,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" : isEs ? "No se pudieron cargar las placas" : "Não foi possível carregar as placas"}
|
||||
</p>
|
||||
<p className="mt-1">
|
||||
{error}. {isEn ? "Check your connection and try again." : isEs ? "Compruebe la conexión y vuelva a intentarlo." : "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" : isEs ? "Reintentar" : "Tentar novamente"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -203,14 +264,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" : isEs ? "Buscar placa" : "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" : isEs ? "Nombre o descripción" : "Nome ou descrição"}
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="field pl-10 text-sm"
|
||||
@@ -221,11 +282,12 @@ export default function PlacasPage() {
|
||||
{filterableColumns.map((column) => {
|
||||
const filterData = filterOptions[column];
|
||||
if (!filterData) return null;
|
||||
const colLabel = isEn ? (HEADER_MAP_EN[column] || column) : isEs ? (HEADER_MAP_ES[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 +301,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) : isEs ? (VALUE_MAP_ES[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 +333,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" : isEs ? "Placas" : "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" : isEs ? "Filtros" : "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" : isEs ? "Limpiar" : "Limpar"}
|
||||
</button>
|
||||
)}
|
||||
</summary>
|
||||
@@ -295,16 +363,34 @@ 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"
|
||||
: isEs
|
||||
? filteredBoards.length === 1
|
||||
? "placa encontrada"
|
||||
: "placas encontradas"
|
||||
: 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" : isEs ? "Ninguna placa coincide con estos filtros" : "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."
|
||||
: isEs
|
||||
? "Elimine algunos filtros o busque por otro nombre."
|
||||
: "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" : isEs ? "Limpiar filtros" : "Limpar filtros"}
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -1,13 +1,27 @@
|
||||
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"],
|
||||
});
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
return paginaMeta({
|
||||
titulo: isEn ? "Compare ESP32 Series: Side-by-Side Table" : isEs ? "Comparar series ESP32: tabla comparativa" : "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."
|
||||
: isEs
|
||||
? "Compare hasta cuatro series de ESP32 frente a frente: procesador, Wi-Fi, Bluetooth, memoria, GPIO, periféricos y seguridad en hardware, con datos de hojas de datos oficiales."
|
||||
: "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"]
|
||||
: isEs
|
||||
? ["comparar ESP32", "ESP32 vs ESP32-S3", "tabla comparativa ESP32", "cuál ESP32 es mejor"]
|
||||
: ["comparar ESP32", "ESP32 vs ESP32-S3", "tabela comparativa ESP32", "qual ESP32 é melhor"],
|
||||
});
|
||||
}
|
||||
|
||||
const faqs = [
|
||||
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.",
|
||||
@@ -22,7 +36,43 @@ const faqs = [
|
||||
},
|
||||
];
|
||||
|
||||
export default function Layout({ children }) {
|
||||
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.",
|
||||
},
|
||||
];
|
||||
|
||||
const faqsEs = [
|
||||
{
|
||||
pergunta: "¿Cómo comparar microcontroladores ESP32 frente a frente?",
|
||||
resposta: "El comparador de ESPDocs le permite seleccionar hasta cuatro series simultáneamente para cotejar arquitectura, frecuencia de reloj, memoria SRAM/PSRAM, estándares de radio (Wi-Fi 4/6, Bluetooth 5/6, 802.15.4), interfaces de periféricos y bloques de seguridad en hardware.",
|
||||
},
|
||||
{
|
||||
pergunta: "¿Cuál es la diferencia entre el ESP32 clásico y el ESP32-S3?",
|
||||
resposta: "El ESP32 clásico utiliza núcleos Xtensa LX6 y Bluetooth clásico/LE. El ESP32-S3 incorpora núcleos Xtensa LX7 con instrucciones vectoriales para inteligencia artificial (TinyML), USB nativo OTG, más GPIOs (45 frente a 36) y Bluetooth 5.0 LE.",
|
||||
},
|
||||
{
|
||||
pergunta: "¿Cuál es la diferencia entre ESP32-C3 y ESP32-C6?",
|
||||
resposta: "El ESP32-C3 es un microcontrolador RISC-V con Wi-Fi 4 y Bluetooth 5 LE. El ESP32-C6 evoluciona a Wi-Fi 6 (802.11ax), Bluetooth 5.4 LE, radio IEEE 802.15.4 para Zigbee 3.0 y Thread 1.3, además de un coprocesador de consumo ultrabajo.",
|
||||
},
|
||||
];
|
||||
|
||||
export default async function Layout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const faqs = isEn ? faqsEn : isEs ? faqsEs : faqsPt;
|
||||
const canonPath = isEn ? "/en/compare" : isEs ? "/es/comparacion" : "/comparacao";
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
@@ -30,9 +80,14 @@ export default function Layout({ children }) {
|
||||
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",
|
||||
nome: isEn ? "ESP32 Series Comparator" : isEs ? "Comparador de series ESP32" : "Comparador de Séries ESP32",
|
||||
descricao: isEn
|
||||
? "Technical comparison table to analyze specifications, pinouts, and features of multiple ESP32 series."
|
||||
: isEs
|
||||
? "Tabla comparativa técnica para analizar especificaciones, patillaje y características de múltiples series de ESP32."
|
||||
: "Tabela comparativa técnica para analisar especificações, pinagens e recursos de múltiplas séries de ESP32.",
|
||||
caminho: canonPath,
|
||||
locale,
|
||||
})
|
||||
),
|
||||
}}
|
||||
@@ -42,8 +97,8 @@ export default function Layout({ children }) {
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Comparar Séries", caminho: "/comparacao" },
|
||||
{ nome: isEn ? "Home" : isEs ? "Inicio" : "Início", caminho: isEn ? "/en" : isEs ? "/es" : "/" },
|
||||
{ nome: isEn ? "Compare Series" : isEs ? "Comparar series" : "Comparar Séries", caminho: canonPath },
|
||||
])
|
||||
),
|
||||
}}
|
||||
|
||||
+332
-111
@@ -3,9 +3,13 @@
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import PageHero from "@/components/PageHero";
|
||||
import { useEffect, useState, Fragment } from "react";
|
||||
import { useEffect, useState, useMemo, Fragment } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import seriesData from "@/public/series.json";
|
||||
import seriesDataPt from "@/public/series.json";
|
||||
import seriesDataEn from "@/data/en/series.json";
|
||||
import seriesDataEs from "@/data/es/series.json";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
import { ArrowRight, ArrowUpRight, Check, ChevronDown, Scale } from "lucide-react";
|
||||
|
||||
const MIN_SERIES = 2;
|
||||
@@ -16,13 +20,257 @@ 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." },
|
||||
]},
|
||||
];
|
||||
|
||||
const COMPARE_FIELDS_ES = [
|
||||
{ category: "General", fields: [
|
||||
{ key: "nome_completo", label: "Nombre completo" },
|
||||
{ key: "descricao", label: "Descripción" },
|
||||
]},
|
||||
{ category: "Disponibilidad y herramientas", fields: [
|
||||
{ key: "esp_idf_minimo", label: "ESP-IDF mínimo" },
|
||||
{ key: "arduino_core", label: "Core Arduino" },
|
||||
{ key: "depuracao", label: "Depuración / JTAG" },
|
||||
{ key: "encapsulamento", label: "Encapsulado" },
|
||||
{ key: "modulos", label: "Módulos disponibles" },
|
||||
]},
|
||||
{ category: "Procesador", fields: [
|
||||
{ key: "arquitetura", label: "Arquitectura" },
|
||||
{ key: "nucleos", label: "Núcleos" },
|
||||
{ key: "frequencia", label: "Frecuencia" },
|
||||
{ key: "coprocessador_ulp", label: "Coprocesador ULP" },
|
||||
{ key: "aceleradores_ia", label: "Aceleradores de IA" },
|
||||
]},
|
||||
{ category: "Conectividad", 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: "Memoria", 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 digitales", 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: "Depuración / 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: "Seguridad", 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 en hardware" },
|
||||
{ key: "seguranca.hmac", label: "HMAC" },
|
||||
{ key: "seguranca.assinatura_digital", label: "Firma digital (DS)" },
|
||||
{ key: "seguranca.key_manager", label: "Key Manager" },
|
||||
{ key: "seguranca.rng", label: "Generador aleatorio (TRNG)" },
|
||||
{ key: "seguranca.criptografia_flash", label: "Cifrado de flash" },
|
||||
{ key: "seguranca.secure_boot", label: "Secure Boot" },
|
||||
{ key: "seguranca.protecao_dpa", label: "Protección contra DPA" },
|
||||
]},
|
||||
{ category: "Interfaces especiales", fields: [
|
||||
{ key: "lcd", label: "LCD" },
|
||||
{ key: "camera", label: "Cámara" },
|
||||
{ key: "mipi_csi", label: "MIPI CSI" },
|
||||
{ key: "mipi_dsi", label: "MIPI DSI" },
|
||||
{ key: "ethernet_mac", label: "Ethernet MAC" },
|
||||
]},
|
||||
{ category: "Especificaciones ambientales", fields: [
|
||||
{ key: "temperatura_operacao", label: "Temp. operación" },
|
||||
{ key: "temperatura_armazenamento", label: "Temp. almacenamiento" },
|
||||
]},
|
||||
];
|
||||
|
||||
export default function Comparacao() {
|
||||
const pathname = usePathname();
|
||||
const isEn = pathname?.startsWith("/en");
|
||||
const isEs = pathname?.startsWith("/es");
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : "pt";
|
||||
const seriesData = isEs ? seriesDataEs : isEn ? seriesDataEn : seriesDataPt;
|
||||
const compareFields = isEs ? COMPARE_FIELDS_ES : isEn ? COMPARE_FIELDS_EN : COMPARE_FIELDS_PT;
|
||||
|
||||
const [selectedSeries, setSelectedSeries] = useState(["ESP32", "ESP32-S3"]);
|
||||
const [soDiferencas, setSoDiferencas] = useState(false);
|
||||
const [collapsedCategories, setCollapsedCategories] = useState({
|
||||
"Interfaces Especiais": true,
|
||||
"Especificações Ambientais": true,
|
||||
});
|
||||
const [collapsedCategories, setCollapsedCategories] = useState(() => ({
|
||||
[isEs ? "Interfaces especiales" : isEn ? "Special Interfaces" : "Interfaces Especiais"]: true,
|
||||
[isEs ? "Especificaciones ambientales" : isEn ? "Environmental Specifications" : "Especificações Ambientais"]: true,
|
||||
}));
|
||||
|
||||
const series = Object.entries(seriesData);
|
||||
|
||||
@@ -32,7 +280,7 @@ export default function Comparacao() {
|
||||
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)) {
|
||||
@@ -46,99 +294,20 @@ export default function Comparacao() {
|
||||
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") {
|
||||
if (!value || value === "Não" || value === "No") return <span className="text-muted">{isEs || isEn ? "No" : "Não"}</span>;
|
||||
if (value === "Sim" || value === "Yes" || value === "Sí") {
|
||||
return (
|
||||
<span className="inline-flex items-center gap-1.5 font-medium text-ok">
|
||||
<Check className="h-4 w-4" aria-hidden="true" />
|
||||
Sim
|
||||
{isEs ? "Sí" : isEn ? "Yes" : "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 valores = (key) => selectedSeries.map((k) => String(valorDe(seriesData[k], key) ?? (isEs || isEn ? "No" : "Não")));
|
||||
const diferem = (key) => new Set(valores(key)).size > 1;
|
||||
|
||||
return (
|
||||
@@ -147,21 +316,51 @@ export default function Comparacao() {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Comparador" }]}
|
||||
isEn={isEn}
|
||||
isEs={isEs}
|
||||
trail={[{ label: isEs ? "Comparador" : isEn ? "Comparator" : "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."
|
||||
label={isEs ? "Hasta cuatro series lado a lado" : isEn ? "Up to four series side by side" : "Até quatro séries lado a lado"}
|
||||
title={isEs ? "Comparador de series ESP32" : isEn ? "ESP32 Series Comparator" : "Comparador de séries"}
|
||||
lede={
|
||||
isEs
|
||||
? "Ponga núcleos, radio, memoria, periféricos y seguridad en la misma tabla y vea lo que realmente cambia de un chip a otro."
|
||||
: 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">Escolha de {MIN_SERIES} a {MAX_SERIES} séries</h2>
|
||||
<h2 id="escolha-titulo" className="text-base font-semibold text-ink">
|
||||
{isEs ? (
|
||||
<>Elija de {MIN_SERIES} a {MAX_SERIES} series</>
|
||||
) : 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">
|
||||
{selectedSeries.length} de {MAX_SERIES} selecionadas
|
||||
{selectedSeries.length === MAX_SERIES && ". Remova uma para trocar."}
|
||||
{isEs ? (
|
||||
<>
|
||||
{selectedSeries.length} de {MAX_SERIES} seleccionadas
|
||||
{selectedSeries.length === MAX_SERIES && ". Elimine una para cambiar."}
|
||||
</>
|
||||
) : 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>
|
||||
@@ -189,7 +388,9 @@ export default function Comparacao() {
|
||||
|
||||
<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>
|
||||
<h2 id="tabela-titulo" className="text-base font-semibold text-ink">
|
||||
{isEs ? "Especificaciones" : 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"
|
||||
@@ -197,22 +398,30 @@ export default function Comparacao() {
|
||||
onChange={(e) => setSoDiferencas(e.target.checked)}
|
||||
className="h-5 w-5 cursor-pointer accent-[var(--accent)]"
|
||||
/>
|
||||
Mostrar só as diferenças
|
||||
{isEs ? "Mostrar solo diferencias" : 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">Comparação das séries {selectedSeries.join(", ")}</caption>
|
||||
<caption className="sr-only">
|
||||
{isEs ? (
|
||||
<>Comparación de las series {selectedSeries.join(", ")}</>
|
||||
) : 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">
|
||||
Especificação
|
||||
{isEs ? "Especificación" : 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={`/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">
|
||||
<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>
|
||||
@@ -264,23 +473,27 @@ export default function Comparacao() {
|
||||
</section>
|
||||
|
||||
<section className="shell section" aria-labelledby="docs-titulo">
|
||||
<h2 id="docs-titulo" className="section-title">Documentação oficial</h2>
|
||||
<h2 id="docs-titulo" className="section-title">
|
||||
{isEs ? "Documentación oficial" : 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={`/series/${seriesKey}`} className="inline-flex min-h-11 items-center font-display text-lg font-semibold tracking-[-0.03em] text-ink hover:text-accent">
|
||||
<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">
|
||||
Datasheet oficial
|
||||
{isEs ? "Datasheet oficial" : isEn ? "Official datasheet" : "Datasheet oficial"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
<span className="sr-only"> (abre em nova aba)</span>
|
||||
<span className="sr-only"> {isEs ? "(abre en una nueva pestaña)" : isEn ? "(opens in a new tab)" : "(abre em nova aba)"}</span>
|
||||
</a>
|
||||
) : (
|
||||
<span className="text-sm text-muted">Datasheet ainda não publicado</span>
|
||||
<span className="text-sm text-muted">
|
||||
{isEs ? "Datasheet aún no publicado" : isEn ? "Datasheet not yet published" : "Datasheet ainda não publicado"}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
@@ -289,11 +502,19 @@ export default function Comparacao() {
|
||||
|
||||
<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>
|
||||
<h2 className="section-title">
|
||||
{isEs ? "¿Desea probar en banco?" : isEn ? "Want to test on the bench?" : "Quer testar na bancada?"}
|
||||
</h2>
|
||||
<p className="mt-3 text-base text-muted">
|
||||
{isEs
|
||||
? "Vea las placas de desarrollo con patillaje, periféricos y enlace a la tienda oficial."
|
||||
: 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="/catalogo" className="btn btn-primary shrink-0">
|
||||
Ver catálogo de placas
|
||||
<Link href={getLocalizedHref("/catalogo", currentLocale)} className="btn btn-primary shrink-0">
|
||||
{isEs ? "Ver catálogo de placas" : isEn ? "View boards catalog" : "Ver catálogo de placas"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -1,23 +1,61 @@
|
||||
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",
|
||||
],
|
||||
});
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
return paginaMeta({
|
||||
titulo: isEs
|
||||
? "ESP Component Registry & IDF Component Manager · ESPDocs"
|
||||
: isEn
|
||||
? "ESP Component Registry & IDF Component Manager · ESPDocs"
|
||||
: "ESP Component Registry & IDF Component Manager · ESPDocs",
|
||||
descricao: isEs
|
||||
? "Catálogo interactivo del ESP Component Registry: controladores de pantalla, LVGL, reconocimiento de voz ESP-SR, RainMaker, BSPs y generador de idf_component.yml."
|
||||
: 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: isEs
|
||||
? [
|
||||
"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",
|
||||
]
|
||||
: 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 faqs = [
|
||||
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.",
|
||||
@@ -36,7 +74,50 @@ const faqs = [
|
||||
},
|
||||
];
|
||||
|
||||
export default function ComponentesLayout({ children }) {
|
||||
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).",
|
||||
},
|
||||
];
|
||||
|
||||
const faqsEs = [
|
||||
{
|
||||
pergunta: "¿Qué es el ESP Component Registry y el IDF Component Manager?",
|
||||
resposta: "El ESP Component Registry (components.espressif.com) es el repositorio oficial de paquetes modulares de Espressif. El IDF Component Manager es la herramienta integrada en ESP-IDF (a partir de v4.4 y estándar en v5.x+) que descarga, compila y resuelve versiones de dependencias automáticamente desde el manifiesto idf_component.yml.",
|
||||
},
|
||||
{
|
||||
pergunta: "¿Cómo agregar un componente a mi proyecto ESP-IDF?",
|
||||
resposta: "Puede ejecutar el comando 'idf.py add-dependency \"namespace/componente^version\"' en la terminal del proyecto (por ejemplo: idf.py add-dependency \"espressif/esp_lvgl_port^2.4.0\") o editar directamente el archivo main/idf_component.yml.",
|
||||
},
|
||||
{
|
||||
pergunta: "¿Cuál es la diferencia entre usar Component Registry y submódulos git?",
|
||||
resposta: "El Component Registry elimina la complejidad de gestionar submódulos Git pesados y versiones manuales. Ofrece versionamiento semántico (^ y ~), resolución automática de dependencias transitivas y compilación modular bajo demanda.",
|
||||
},
|
||||
{
|
||||
pergunta: "¿Puedo crear y publicar mis propios componentes?",
|
||||
resposta: "Sí, cualquier desarrollador o empresa puede publicar componentes públicos o privados en el ESP Component Registry utilizando la herramienta oficial Compote CLI (pip install idf-component-manager).",
|
||||
},
|
||||
];
|
||||
|
||||
export default async function ComponentesLayout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const faqs = isEs ? faqsEs : isEn ? faqsEn : faqsPt;
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
@@ -44,8 +125,8 @@ export default function ComponentesLayout({ children }) {
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "ESP Component Registry", caminho: "/componentes" },
|
||||
{ nome: isEs ? "Inicio" : isEn ? "Home" : "Início", caminho: isEs ? "/es" : isEn ? "/en" : "/" },
|
||||
{ nome: "ESP Component Registry", caminho: isEs ? "/es/componentes" : isEn ? "/en/components" : "/componentes" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
@@ -61,9 +142,18 @@ export default function ComponentesLayout({ children }) {
|
||||
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",
|
||||
nome: isEs
|
||||
? "Hub de ESP Component Registry & Generador de Manifiesto"
|
||||
: isEn
|
||||
? "ESP Component Registry Hub & Manifest Builder"
|
||||
: "Hub do ESP Component Registry & Construtor de Manifesto",
|
||||
descricao: isEs
|
||||
? "Catálogo curado y generador de manifiesto idf_component.yml para componentes modulares de ESP-IDF."
|
||||
: 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: isEs ? "/es/componentes" : isEn ? "/en/components" : "/componentes",
|
||||
locale,
|
||||
})
|
||||
),
|
||||
}}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
"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 * as componentesEs from "@/lib/data/es/componentes";
|
||||
import {
|
||||
ArrowUpRight,
|
||||
Box,
|
||||
@@ -44,6 +43,11 @@ const ICONES_CATEGORIA = {
|
||||
};
|
||||
|
||||
export default function ComponentRegistryPage() {
|
||||
const pathname = usePathname();
|
||||
const isEn = pathname?.startsWith("/en");
|
||||
const isEs = pathname?.startsWith("/es");
|
||||
const { CATEGORIAS_COMPONENTES, COMPONENTES_REGISTRY, GUIA_COMPONENT_MANAGER } = isEs ? componentesEs : isEn ? componentesEn : componentesPt;
|
||||
|
||||
const [busca, setBusca] = useState("");
|
||||
const [categoriaAtiva, setCategoriaAtiva] = useState("todos");
|
||||
const [chipFiltro, setChipFiltro] = useState("todos");
|
||||
@@ -74,7 +78,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 +100,23 @@ export default function ComponentRegistryPage() {
|
||||
);
|
||||
|
||||
if (selecionados.length === 0) {
|
||||
return `# Nenhum componente selecionado.\n# Clique em "+ Adicionar ao Manifesto" nos cards abaixo.`;
|
||||
return isEs
|
||||
? `# No hay componentes seleccionados.\n# Haga clic en "+ Agregar al manifiesto" en las tarjetas de abajo.`
|
||||
: 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 = isEs
|
||||
? `# main/idf_component.yml\n# Generado mediante ESPDocs Component Hub (https://espdocs.cienciaembarcada.com.br/es/componentes)\n\ndependencies:\n`
|
||||
: 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, isEs]);
|
||||
|
||||
const copiarManifesto = () => {
|
||||
navigator.clipboard.writeText(manifestoYaml);
|
||||
@@ -138,40 +150,50 @@ export default function ComponentRegistryPage() {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Component Registry" }]}
|
||||
isEn={isEn}
|
||||
isEs={isEs}
|
||||
trail={[{ label: isEs ? "Component Registry" : 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={
|
||||
isEs
|
||||
? "El catálogo oficial de paquetes reutilizables de Espressif para ESP-IDF. Elija controladores, voz y pilas industriales, copie el comando y genere el manifiesto del proyecto."
|
||||
: 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
|
||||
{isEs ? "Abrir el 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"> {isEs ? "(abre en una nueva pestaña)" : isEn ? "(opens in a new tab)" : "(abre em nova aba)"}</span>
|
||||
</a>
|
||||
<a href="#manifesto-builder" className="btn btn-ghost">
|
||||
Gerar idf_component.yml
|
||||
{isEs ? "Generar 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={isEs ? "Búsqueda y filtros" : 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">
|
||||
{isEs ? "Buscar por nombre, namespace o etiqueta" : 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={isEs ? "Buscar por nombre, namespace o etiqueta" : 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">{isEs ? "Categoría" : 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 +201,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" ? (isEs ? "Todos" : isEn ? "All" : "Todos") : cat.nome.replace(/\s*\(.*\)/, "").split(",")[0].split(" &")[0]}
|
||||
<span className="tabular-nums opacity-80">{contagem}</span>
|
||||
</button>
|
||||
);
|
||||
@@ -188,11 +210,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">{isEs ? "Chip compatible" : 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" ? (isEs ? "Todos" : isEn ? "All" : "Todos") : chip}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -203,17 +225,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 ? (isEs ? "componente" : isEn ? "component" : "componente") : (isEs ? "componentes" : 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
|
||||
{isEs ? "Limpiar 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"}
|
||||
{isEs ? "Manifiesto:" : isEn ? "Manifest:" : "Manifesto:"} {componentesSelecionados.length} {componentesSelecionados.length === 1 ? (isEs ? "componente" : isEn ? "component" : "componente") : (isEs ? "componentes" : isEn ? "components" : "componentes")}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -221,9 +243,19 @@ 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">
|
||||
{isEs ? "No se encontraron componentes" : isEn ? "No components found" : "Nenhum componente encontrado"}
|
||||
</h3>
|
||||
<p className="mx-auto mt-2 max-w-md text-sm text-muted">
|
||||
{isEs
|
||||
? "Busque por un término más general o regrese a todas las categorías."
|
||||
: 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">
|
||||
{isEs ? "Limpiar filtros" : isEn ? "Clear filters" : "Limpar filtros"}
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="mt-6 grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
@@ -242,7 +274,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
|
||||
{isEs ? "Oficial" : isEn ? "Official" : "Oficial"}
|
||||
</span>
|
||||
)}
|
||||
</p>
|
||||
@@ -266,12 +298,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={isEs ? `Copiar comando para agregar ${comp.name}` : 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 ? (isEs ? "Comando copiado" : 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 +319,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 ? (isEs ? "En manifiesto" : isEn ? "In manifest" : "No manifesto") : (isEs ? "Agregar al manifiesto" : 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={isEs ? `Abrir ${comp.name} en el registro oficial (nueva pestaña)` : 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 +342,44 @@ 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">{isEs ? "Generador de manifiesto" : isEn ? "Manifest generator" : "Gerador de manifesto"}</p>
|
||||
<h2 id="manifesto-titulo" className="section-title mt-3">
|
||||
{isEs ? "Su idf_component.yml" : 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.
|
||||
{isEs ? (
|
||||
<>Guarde el archivo en la carpeta <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono">main/</code> del proyecto y ESP-IDF descargará todas las bibliotecas durante la compilación.</>
|
||||
) : 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 ? (isEs ? "Copiado" : isEn ? "Copied" : "Copiado") : (isEs ? "Copiar YAML" : 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
|
||||
{isEs ? "Descargar .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
|
||||
{isEs ? "Limpiar" : 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={isEs ? "Contenido de idf_component.yml" : 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={isEs ? "Componentes incluidos" : isEn ? "Included components" : "Componentes incluídos"}>
|
||||
{componentesSelecionados.map((id) => {
|
||||
const c = COMPONENTES_REGISTRY.find((item) => item.id === id);
|
||||
if (!c) return null;
|
||||
@@ -351,7 +390,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={isEs ? `Eliminar ${c.name} del manifiesto` : 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 +403,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={isEs ? "Guía rápida" : 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 +416,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
|
||||
{isEs ? "Comandos esenciales" : isEn ? "Essential commands" : "Comandos essenciais"}
|
||||
</h3>
|
||||
<ul className="mt-4 space-y-3">
|
||||
{GUIA_COMPONENT_MANAGER.comandosCli.map((cmd, i) => (
|
||||
@@ -392,7 +431,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}` ? (isEs ? "Copiado" : isEn ? "Copied" : "Copiado") : (isEs ? "Copiar" : isEn ? "Copy" : "Copiar")}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
@@ -401,13 +440,31 @@ 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
|
||||
{isEs ? "Versionamiento semántico en 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>
|
||||
{isEs ? (
|
||||
<>
|
||||
<li><code>^1.2.0</code>: acepta actualizaciones menores y correcciones (1.2.1, 1.3.0), pero bloquea cambios importantes de API (2.0.0). <strong>Recomendado.</strong></li>
|
||||
<li><code>~1.2.0</code>: acepta solo correcciones de errores (1.2.1, 1.2.5).</li>
|
||||
<li><code>1.2.0</code>: bloquea en esta versión exacta.</li>
|
||||
<li><code>*</code>: acepta cualquier versión. Evite en producción.</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>
|
||||
|
||||
@@ -1,22 +1,58 @@
|
||||
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",
|
||||
],
|
||||
});
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
return paginaMeta({
|
||||
titulo: isEs
|
||||
? "Diagnóstico de errores comunes en ESP32: Guía profesional"
|
||||
: isEn
|
||||
? "Common ESP32 Errors & Diagnostics: Professional Guide"
|
||||
: "Diagnóstico de Erros Comuns no ESP32: Guia Profissional",
|
||||
descricao: isEs
|
||||
? "Guía técnica definitiva para identificar y solucionar Brownout, Guru Meditation, Task Watchdog, Stack Overflow, fugas de memoria y fallas de arranque en ESP32 (Arduino y ESP-IDF)."
|
||||
: 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: isEs
|
||||
? [
|
||||
"errores comunes ESP32",
|
||||
"brownout detector was triggered",
|
||||
"guru meditation error",
|
||||
"task watchdog got triggered",
|
||||
"stack canary watchpoint triggered",
|
||||
"cómo depurar ESP32",
|
||||
"ESP32 reiniciando en bucle",
|
||||
"failed to connect to esp32",
|
||||
]
|
||||
: 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 faqs = [
|
||||
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+.",
|
||||
@@ -35,7 +71,50 @@ const faqs = [
|
||||
},
|
||||
];
|
||||
|
||||
export default function DiagnosticoLayout({ children }) {
|
||||
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.",
|
||||
},
|
||||
];
|
||||
|
||||
const faqsEs = [
|
||||
{
|
||||
pergunta: "¿Qué causa el error 'Brownout detector was triggered' en el ESP32?",
|
||||
resposta: "Ocurre cuando la tensión en el pin 3V3 cae por debajo de 2.8V ~ 2.43V debido a picos rápidos de corriente de la radio Wi-Fi/BLE (que superan los 500mA), cables USB delgados o un regulador LDO inadecuado. La solución de ingeniería implica agregar condensadores Low-ESR de 10µF a 100µF cerca de VCC y usar reguladores LDO robustos de más de 600mA.",
|
||||
},
|
||||
{
|
||||
pergunta: "¿Cómo solucionar el 'Guru Meditation Error (LoadProhibited)'?",
|
||||
resposta: "LoadProhibited indica un intento de acceder a un puntero nulo (NULL) o inválido en la memoria. La solución consiste en utilizar Espressif Exception Decoder o addr2line para localizar la línea exacta en el código e implementar comprobaciones defensivas como if (puntero != NULL).",
|
||||
},
|
||||
{
|
||||
pergunta: "¿Por qué se activa el Task Watchdog Timer (TWDT) en FreeRTOS?",
|
||||
resposta: "El TWDT se activa cuando una tarea de mayor prioridad monopoliza la CPU en un bucle bloqueante (por ejemplo: while(1) sin vTaskDelay), impidiendo que la tarea IDLE alimente el watchdog del sistema operativo.",
|
||||
},
|
||||
{
|
||||
pergunta: "¿Por qué fallan las conexiones HTTPS y TLS con el código -0x2700 en ESP32?",
|
||||
resposta: "Porque al encenderse, el reloj interno del ESP32 comienza en el año 1970. El validador de certificados TLS considera inválido el certificado del servidor por estar en el 'futuro'. Sincronizar el reloj mediante SNTP (configTime) antes de la conexión resuelve el problema.",
|
||||
},
|
||||
];
|
||||
|
||||
export default async function DiagnosticoLayout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const faqs = isEs ? faqsEs : isEn ? faqsEn : faqsPt;
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
@@ -43,8 +122,8 @@ export default function DiagnosticoLayout({ children }) {
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Diagnóstico & Erros Comuns", caminho: "/diagnostico" },
|
||||
{ nome: isEs ? "Inicio" : isEn ? "Home" : "Início", caminho: isEs ? "/es" : isEn ? "/en" : "/" },
|
||||
{ nome: isEs ? "Diagnóstico y errores comunes" : isEn ? "Diagnostics & Common Errors" : "Diagnóstico & Erros Comuns", caminho: isEs ? "/es/diagnostico" : isEn ? "/en/diagnostics" : "/diagnostico" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
@@ -62,9 +141,14 @@ export default function DiagnosticoLayout({ children }) {
|
||||
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",
|
||||
nome: isEs ? "Guía de diagnóstico y errores en ESP32" : isEn ? "ESP32 Error Diagnostics & Debugging Guide" : "Guia de Diagnóstico e Erros no ESP32",
|
||||
descricao: isEs
|
||||
? "Herramienta y guía técnica de análisis de fallas, pánicos de CPU y decodificación de registros en ESP32."
|
||||
: 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: isEs ? "/es/diagnostico" : isEn ? "/en/diagnostics" : "/diagnostico",
|
||||
locale,
|
||||
})
|
||||
),
|
||||
}}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
"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 * as diagnosticoEs from "@/lib/data/es/diagnostico";
|
||||
import {
|
||||
Activity,
|
||||
AlertTriangle,
|
||||
@@ -38,7 +36,21 @@ 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 EXEMPLOS_LOG_ES = [
|
||||
["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"],
|
||||
@@ -47,10 +59,15 @@ const EXEMPLOS_LOG = [
|
||||
|
||||
const GRAVIDADE = {
|
||||
"Crítica": "text-danger",
|
||||
"Critical": "text-danger",
|
||||
Alta: "text-gold",
|
||||
High: "text-gold",
|
||||
"Média": "text-accent",
|
||||
Medium: "text-accent",
|
||||
Media: "text-accent",
|
||||
};
|
||||
|
||||
const CHECKLISTS = [
|
||||
const CHECKLISTS_PT = [
|
||||
{
|
||||
icon: Zap,
|
||||
titulo: "Hardware e alimentação",
|
||||
@@ -73,7 +90,60 @@ 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.",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const CHECKLISTS_ES = [
|
||||
{
|
||||
icon: Zap,
|
||||
titulo: "Hardware y alimentación",
|
||||
itens: [
|
||||
"Condensador de 10 µF a 100 µF de bajo ESR en VCC, más uno cerámico de 100 nF junto al chip.",
|
||||
"Regulador LDO dimensionado para picos de 600 mA a 1 A, con margen térmico.",
|
||||
"Ningún periférico forzando niveles lógicos en los pines de strapping durante el arranque.",
|
||||
"Condensador de 10 µF o 1 µF en el pin EN (RST) para auto-reset estable durante la programación.",
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Layers,
|
||||
titulo: "Firmware y FreeRTOS",
|
||||
itens: [
|
||||
"Cada tarea de FreeRTOS cede la CPU con vTaskDelay, colas o semáforos.",
|
||||
"Cada ISR marcada con IRAM_ATTR y sin llamadas bloqueantes.",
|
||||
"Sin uso continuo de String de Arduino en bucles para evitar la fragmentación del heap.",
|
||||
"Hora sincronizada mediante SNTP antes de abrir conexiones TLS/HTTPS.",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default function DiagnosticoPage() {
|
||||
const pathname = usePathname();
|
||||
const isEn = pathname?.startsWith("/en");
|
||||
const isEs = pathname?.startsWith("/es");
|
||||
const { categoriasDiagnostico, sintomasRapidos, errosCatalogo, regrasDecodificadorLog } = isEs ? diagnosticoEs : isEn ? diagnosticoEn : diagnosticoPt;
|
||||
const exemplosLog = isEs ? EXEMPLOS_LOG_ES : isEn ? EXEMPLOS_LOG_EN : EXEMPLOS_LOG_PT;
|
||||
const checklists = isEs ? CHECKLISTS_ES : isEn ? CHECKLISTS_EN : CHECKLISTS_PT;
|
||||
|
||||
const [termoBusca, setTermoBusca] = useState("");
|
||||
const [categoriaAtiva, setCategoriaAtiva] = useState("todos");
|
||||
const [sintomaAtivo, setSintomaAtivo] = useState(null);
|
||||
@@ -101,14 +171,34 @@ 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(
|
||||
isEs
|
||||
? {
|
||||
titulo: "Patrón de error no categorizado automáticamente",
|
||||
tipo: "Desconocido",
|
||||
explicacao:
|
||||
"No identificamos una firma clásica de Guru Meditation o Brownout en este fragmento. Verifique que la velocidad de baudios (ej: 115200) sea correcta y si el encabezado 'rst:' o 'panic' está presente.",
|
||||
acaoRecomendada:
|
||||
"Busque palabras clave como 'Guru Meditation', 'rst:', 'LoadProhibited', 'watchdog' o 'panic' en la consola serie.",
|
||||
}
|
||||
: 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 +224,7 @@ export default function DiagnosticoPage() {
|
||||
|
||||
return matchCategoria && matchSintoma && matchBusca;
|
||||
});
|
||||
}, [categoriaAtiva, sintomaAtivo, termoBusca]);
|
||||
}, [categoriaAtiva, sintomaAtivo, termoBusca, errosCatalogo]);
|
||||
|
||||
const temFiltroAtivo =
|
||||
termoBusca.trim() !== "" ||
|
||||
@@ -156,7 +246,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 +254,19 @@ export default function DiagnosticoPage() {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Diagnóstico" }]}
|
||||
isEn={isEn}
|
||||
isEs={isEs}
|
||||
trail={[{ label: isEs ? "Diagnóstico" : 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={isEs ? "Depuración de firmware" : isEn ? "Firmware Debugging" : "Depuração de firmware"}
|
||||
title={isEs ? "Diagnóstico de fallas del ESP32" : isEn ? "ESP32 Diagnostics and Crash Decoder" : "Diagnóstico de falhas do ESP32"}
|
||||
lede={
|
||||
isEs
|
||||
? "Comprenda la causa raíz de las fallas por Brownout, Guru Meditation, Watchdog y Stack Overflow, y aplique la corrección de ingeniería en lugar de soluciones improvisadas."
|
||||
: 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 +274,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
|
||||
{isEs ? "Basado en el artículo de 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"> {isEs ? "(abre en una nueva pestaña)" : isEn ? "(opens in a new tab)" : "(abre em nova aba)"}</span>
|
||||
</a>
|
||||
</PageHero>
|
||||
|
||||
@@ -187,12 +284,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">
|
||||
{isEs ? "Pegue el registro y descubra la causa" : isEn ? "Paste the log to see the cause" : "Cole o log e veja a causa"}
|
||||
</h2>
|
||||
<p className="mt-2 text-sm text-muted">
|
||||
{isEs ? "Copie el fragmento del monitor serie. El diagnóstico aparece al instante." : 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">{isEs ? "Probar con" : 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 +302,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">
|
||||
{isEs ? "Registro del monitor serie" : 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={isEs ? "Pegue el registro del monitor serie aquí" : 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
|
||||
{isEs ? "Limpiar" : isEn ? "Clear" : "Limpar"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -228,8 +331,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">{isEs ? "Causa probable:" : isEn ? "Likely cause:" : "Causa provável:"}</strong> {resultadoLog.explicacao}</p>
|
||||
<p><strong className="font-semibold text-ink">{isEs ? "Qué hacer:" : isEn ? "What to do:" : "O que fazer:"}</strong> {resultadoLog.acaoRecomendada}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -238,11 +341,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">
|
||||
{isEs ? "Catálogo de fallas" : 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">
|
||||
{isEs ? "Buscar por error, síntoma o mensaje serie" : 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 +357,14 @@ export default function DiagnosticoPage() {
|
||||
type="search"
|
||||
value={termoBusca}
|
||||
onChange={(e) => setTermoBusca(e.target.value)}
|
||||
placeholder="Buscar erro, sintoma ou mensagem"
|
||||
placeholder={isEs ? "Buscar error, síntoma o mensaje" : 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">{isEs ? "Síntoma" : 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 +375,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">{isEs ? "Área" : 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
|
||||
{isEs ? "Todas" : isEn ? "All" : "Todas"}
|
||||
<span className="tabular-nums opacity-80">{errosCatalogo.length}</span>
|
||||
</button>
|
||||
{categoriasDiagnostico.map((cat) => {
|
||||
@@ -292,13 +399,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 ? (isEs ? "falla" : isEn ? "fault" : "falha") : (isEs ? "fallas" : isEn ? "faults" : "falhas")}
|
||||
{totalFiltros > 0 && <span className="font-normal text-muted">{isEs ? " con los filtros actuales" : 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
|
||||
{isEs ? "Restablecer filtros" : isEn ? "Reset filters" : "Redefinir filtros"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -307,16 +414,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">
|
||||
{isEs ? "Ninguna falla coincide con estos filtros" : 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">
|
||||
{isEs ? "Busque por un término más general o elimine el síntoma y el área seleccionados." : 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">
|
||||
{isEs ? "Limpiar filtros" : 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 || (isEs ? "# Ejemplo no aplicable" : 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 +449,15 @@ 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"}`}>
|
||||
{isEs ? (
|
||||
<>Severidad {erro.gravidade.toLowerCase()}</>
|
||||
) : 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 +474,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
|
||||
{isEs ? "Cómo aparece en el monitor serie" : 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}` ? (isEs ? "Copiado" : isEn ? "Copied" : "Copiado") : (isEs ? "Copiar registro" : isEn ? "Copy log" : "Copiar log")}
|
||||
</button>
|
||||
</div>
|
||||
<div className="code-panel mt-1">
|
||||
@@ -368,7 +489,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
|
||||
{isEs ? "Causa raíz" : isEn ? "Root cause" : "Causa raiz"}
|
||||
</h4>
|
||||
<p className="callout mt-2">{erro.causaRaiz}</p>
|
||||
</div>
|
||||
@@ -377,17 +498,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
|
||||
{isEs ? "La solución improvisada común" : 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">{isEs ? "Consecuencia:" : 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
|
||||
{isEs ? "La solución de ingeniería" : 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 +524,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={isEs ? "Lenguaje del ejemplo" : isEn ? "Example language" : "Linguagem do exemplo"} className="flex flex-wrap gap-2">
|
||||
{[
|
||||
["arduino", "Arduino C++"],
|
||||
["espidf", "ESP-IDF (C)"],
|
||||
@@ -416,7 +537,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}` ? (isEs ? "Copiado" : isEn ? "Copied" : "Copiado") : (isEs ? "Copiar código" : isEn ? "Copy code" : "Copiar código")}
|
||||
</button>
|
||||
</div>
|
||||
<div className="code-panel mt-3">
|
||||
@@ -426,7 +547,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">{isEs ? "Consejo de ingeniería:" : isEn ? "Engineering tip:" : "Dica de engenharia:"}</strong> {erro.dicaPro}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -438,10 +559,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">
|
||||
{isEs ? "Lista de verificación previa a campo" : isEn ? "Pre-deployment checklist" : "Checklist antes de ir para campo"}
|
||||
</h2>
|
||||
<p className="mt-3 max-w-2xl text-base text-muted">
|
||||
{isEs ? "Elementos esenciales para validar en hardware y firmware antes de entregar el producto." : 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,18 @@ 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 frameworksDataEs from "@/data/es/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 isEs = locale === "es";
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : "pt";
|
||||
const frameworksData = isEs ? frameworksDataEs : isEn ? frameworksDataEn : frameworksDataPt;
|
||||
const framework = frameworksData[key];
|
||||
|
||||
if (!framework) {
|
||||
@@ -25,15 +32,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: isEs ? "Inicio" : isEn ? "Home" : "Início", caminho: isEs ? "/es" : isEn ? "/en" : "/" },
|
||||
{ nome: "Frameworks", caminho: getLocalizedHref("/frameworks", currentLocale) },
|
||||
{ nome: framework.nome, caminho: getLocalizedHref(`/frameworks/${encodeURIComponent(key)}`, currentLocale) },
|
||||
])),
|
||||
}}
|
||||
/>
|
||||
@@ -42,7 +49,9 @@ export default async function FrameworkDetail({ params }) {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Frameworks e SDKs", href: "/frameworks" }, { label: framework.nome }]}
|
||||
isEn={isEn}
|
||||
isEs={isEs}
|
||||
trail={[{ label: isEs ? "Frameworks y SDKs" : isEn ? "Frameworks & SDKs" : "Frameworks e SDKs", href: getLocalizedHref("/frameworks", currentLocale) }, { label: framework.nome }]}
|
||||
icon={Layers}
|
||||
label={framework.tipo}
|
||||
title={framework.nome}
|
||||
@@ -51,40 +60,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
|
||||
{isEs ? "Documentación 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
|
||||
{isEs ? "Repositorio en 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={isEs ? "Resumen" : 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">{isEs ? "Lenguaje" : 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">{isEs ? "Categoría" : 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">{isEs ? "Objetivo principal" : 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={isEs ? "Funciones y aplicaciones" : 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">
|
||||
{isEs ? "Funciones destacadas" : 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 +107,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">
|
||||
{isEs ? "Cuándo usar" : 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 +126,35 @@ 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
|
||||
{isEs ? "ESP-IDF 4.4 o 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">
|
||||
{isEs ? "Módulos con ESP Component Registry" : 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.
|
||||
{isEs ? (
|
||||
<>
|
||||
En los proyectos ESP-IDF v4.4+ y v5.x, las bibliotecas ya no necesitan agregarse como submódulos Git. Utilice el{" "}
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code> y el comando{" "}
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf.py add-dependency</code> para descargar controladores de pantalla (LVGL), pilas industriales (Modbus), RainMaker y más.
|
||||
</>
|
||||
) : 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">
|
||||
{isEs ? "Explorar componentes" : isEn ? "Explore components" : "Explorar componentes"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
@@ -137,9 +168,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
|
||||
{isEs ? "Ver todos los frameworks" : isEn ? "View all frameworks" : "Ver todos os frameworks"}
|
||||
</Link>
|
||||
</div>
|
||||
</main>
|
||||
@@ -150,31 +181,52 @@ 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 isEs = locale === "es";
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : "pt";
|
||||
const frameworksData = isEs ? frameworksDataEs : isEn ? frameworksDataEn : frameworksDataPt;
|
||||
const framework = frameworksData[key];
|
||||
|
||||
if (!framework) {
|
||||
return { title: "Framework não encontrado", robots: { index: false, follow: false } };
|
||||
return { title: isEs ? "Framework no encontrado" : 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: isEs ? `${framework.nome} para ESP32 · Guía técnica` : isEn ? `${framework.nome} for ESP32 · Technical Guide` : `${framework.nome} para ESP32 · Guia Técnico`,
|
||||
descricao: isEs
|
||||
? `${framework.nome_completo}: ${framework.descricao} Guía con ejemplos prácticos de código y casos de uso.`
|
||||
: 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: isEs
|
||||
? [
|
||||
framework.nome, framework.nome_completo,
|
||||
`${framework.nome} ESP32`, `programar ESP32 con ${framework.nome}`,
|
||||
"ESP32", "framework ESP32",
|
||||
]
|
||||
: 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,
|
||||
}));
|
||||
}
|
||||
@@ -1,25 +1,72 @@
|
||||
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 async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
return {
|
||||
...paginaMeta({
|
||||
titulo: isEs
|
||||
? "Frameworks y SDKs para ESP32: Guía completa y comparativa"
|
||||
: isEn
|
||||
? "ESP32 Frameworks & SDKs: Complete Guide and Comparison"
|
||||
: "Frameworks & SDKs para ESP32: Guia Completo e Comparativo",
|
||||
descricao: isEs
|
||||
? "Guía completa de desarrollo: ESP-IDF, ESP-RainMaker, ESP-Matter, Rust, ESP-ADF, ESP-SR, ESP-WHO, Arduino y MicroPython con ejemplos de código."
|
||||
: 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,
|
||||
keywords: isEs
|
||||
? [
|
||||
"ESP-IDF",
|
||||
"ESP-RainMaker",
|
||||
"ESP-Matter",
|
||||
"Rust ESP32",
|
||||
"ESP-SR",
|
||||
"ESP-ADF",
|
||||
"ESP-IoT-Solution",
|
||||
"Arduino ESP32",
|
||||
"MicroPython ESP32",
|
||||
"frameworks ESP32",
|
||||
"programar ESP32",
|
||||
]
|
||||
: 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 function FrameworksLayout({ children }) {
|
||||
export default async function FrameworksLayout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
@@ -27,8 +74,8 @@ export default function FrameworksLayout({ children }) {
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Frameworks", caminho: "/frameworks" },
|
||||
{ nome: isEs ? "Inicio" : isEn ? "Home" : "Início", caminho: isEs ? "/es" : isEn ? "/en" : "/" },
|
||||
{ nome: "Frameworks", caminho: isEs ? "/es/frameworks" : isEn ? "/en/frameworks" : "/frameworks" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
|
||||
@@ -3,10 +3,14 @@ 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 frameworksDataEs from "@/data/es/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 +43,80 @@ 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],
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const GUIAS_ES = [
|
||||
{
|
||||
icon: GraduationCap,
|
||||
titulo: "Estoy comenzando",
|
||||
texto: "Arduino o MicroPython son los caminos más rápidos para probar sensores y APIs. Para producto, elija ESP-IDF o Rust.",
|
||||
links: [
|
||||
["Arduino", "/frameworks/Arduino"],
|
||||
["MicroPython", "/frameworks/MicroPython"],
|
||||
["Rust", "/frameworks/Rust-ESP"],
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Cloud,
|
||||
titulo: "Nube y hogar conectado",
|
||||
texto: "ESP-Matter para interoperabilidad, ESP-RainMaker para nube lista y Zigbee para redes locales de bajo consumo.",
|
||||
links: [
|
||||
["RainMaker", "/frameworks/ESP-RainMaker"],
|
||||
["Matter", "/frameworks/ESP-Matter"],
|
||||
["Zigbee", "/frameworks/ESP-Zigbee-SDK"],
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Sparkles,
|
||||
titulo: "Audio, voz e IA",
|
||||
texto: "ESP-ADF para procesamiento de audio, ESP-SR para reconocimiento de voz offline y ESP-NN para acelerar TinyML.",
|
||||
links: [
|
||||
["Audio", "/frameworks/ESP-ADF", Music],
|
||||
["Voz", "/frameworks/ESP-SR", Mic],
|
||||
["IA", "/frameworks/ESP-NN", Brain],
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default async function Frameworks({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : "pt";
|
||||
const frameworksData = isEs ? frameworksDataEs : isEn ? frameworksDataEn : frameworksDataPt;
|
||||
const frameworks = Object.entries(frameworksData);
|
||||
const guias = isEs ? GUIAS_ES : isEn ? GUIAS_EN : GUIAS_PT;
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
@@ -48,16 +124,24 @@ export default function Frameworks() {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Frameworks e SDKs" }]}
|
||||
isEn={isEn}
|
||||
isEs={isEs}
|
||||
trail={[{ label: isEs ? "Frameworks y SDKs" : 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={isEs ? `${frameworks.length} frameworks y SDKs` : isEn ? `${frameworks.length} frameworks and SDKs` : `${frameworks.length} frameworks e SDKs`}
|
||||
title={isEs ? "Frameworks y SDKs de ESP32" : isEn ? "ESP32 Frameworks and SDKs" : "Frameworks e SDKs do ESP32"}
|
||||
lede={
|
||||
isEs
|
||||
? "Desde C/C++ nativo con FreeRTOS hasta Rust, nube IoT, reconocimiento de voz, audio y Matter. Elija según lo que desee construir."
|
||||
: 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={isEs ? "Por dónde empezar" : 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 +151,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 +168,46 @@ 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
|
||||
{isEs ? "Arquitectura 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>.
|
||||
{isEs ? (
|
||||
<>
|
||||
Instale controladores de pantalla (LVGL), pilas industriales (Modbus), integraciones en la nube y paquetes de soporte para placas
|
||||
(BSPs) con una sola línea en su manifiesto <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">
|
||||
{isEs ? "Explorar componentes" : 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={isEs ? "Todos" : isEn ? "All" : "Todos"}
|
||||
title={isEs ? "Todos los frameworks" : isEn ? "All frameworks" : "Todos os frameworks"}
|
||||
lede={isEs ? "Cada ficha ofrece funciones, aplicaciones ideales, ejemplos de código y enlaces oficiales." : 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 +224,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
|
||||
{isEs ? "Ver detalles y ejemplo" : 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>
|
||||
|
||||
@@ -1,28 +1,69 @@
|
||||
import { paginaMeta, jsonLd } from "@/lib/seo";
|
||||
import { categoriasGlossario } from "@/lib/glossarioData";
|
||||
import { categoriasGlossario as categoriasGlossarioPt } from "@/lib/glossarioData";
|
||||
import { categoriasGlossario as categoriasGlossarioEn } from "@/lib/data/en/glossario.js";
|
||||
import { categoriasGlossario as categoriasGlossarioEs } from "@/lib/data/es/glossario.js";
|
||||
|
||||
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 async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
return paginaMeta({
|
||||
titulo: isEs
|
||||
? "Glosario técnico de ESP32: Términos y conceptos"
|
||||
: isEn
|
||||
? "ESP32 Technical Glossary: Terms and Concepts"
|
||||
: "Glossário Técnico do ESP32: Termos e Conceitos",
|
||||
descricao: isEs
|
||||
? "Más de 50 conceptos esenciales de ESP32 explicados: GPIO, Strapping Pins, ULP, PSRAM, FreeRTOS, eFuse, Deep Sleep, OTA, Secure Boot, ECDSA, Matter y Thread."
|
||||
: 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: isEs
|
||||
? [
|
||||
"glosario ESP32",
|
||||
"qué es GPIO",
|
||||
"qué son strapping pins",
|
||||
"qué es ESP32 ULP",
|
||||
"qué es ESP32 PSRAM",
|
||||
"términos técnicos microcontrolador",
|
||||
"conceptos ESP32 hardware",
|
||||
]
|
||||
: 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 isEs = locale === "es";
|
||||
const categorias = isEs ? categoriasGlossarioEs : isEn ? categoriasGlossarioEn : categoriasGlossarioPt;
|
||||
|
||||
export default function GlossarioLayout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.glossario(categoriasGlossario)),
|
||||
__html: JSON.stringify(jsonLd.glossario(categorias, locale)),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
@@ -30,8 +71,8 @@ export default function GlossarioLayout({ children }) {
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Glossário Técnico", caminho: "/glossario" },
|
||||
{ nome: isEs ? "Inicio" : isEn ? "Home" : "Início", caminho: isEs ? "/es" : isEn ? "/en" : "/" },
|
||||
{ nome: isEs ? "Glosario técnico" : isEn ? "Technical Glossary" : "Glossário Técnico", caminho: isEs ? "/es/glosario" : isEn ? "/en/glossary" : "/glossario" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
@@ -41,9 +82,14 @@ export default function GlossarioLayout({ children }) {
|
||||
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",
|
||||
nome: isEs ? "Glosario técnico de ESP32" : isEn ? "ESP32 Technical Glossary" : "Glossário Técnico do ESP32",
|
||||
descricao: isEs
|
||||
? "Enciclopedia de términos técnicos y conceptos de hardware y software del ecosistema ESP32."
|
||||
: 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: isEs ? "/es/glosario" : isEn ? "/en/glossary" : "/glossario",
|
||||
locale,
|
||||
})
|
||||
),
|
||||
}}
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
"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 * as glossarioEs from "@/lib/data/es/glossario";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
import {
|
||||
ArrowRight,
|
||||
BookOpen,
|
||||
@@ -35,6 +39,12 @@ 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 isEs = pathname?.startsWith("/es");
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : "pt";
|
||||
const { categoriasGlossario } = isEs ? glossarioEs : isEn ? glossarioEn : glossarioPt;
|
||||
|
||||
const [busca, setBusca] = useState("");
|
||||
const [categoriaSelecionada, setCategoriaSelecionada] = useState("todas");
|
||||
const [letraFiltro, setLetraFiltro] = useState(null);
|
||||
@@ -53,7 +63,7 @@ export default function GlossarioPage() {
|
||||
primeiraLetra: t.termo.charAt(0).toUpperCase(),
|
||||
}))
|
||||
),
|
||||
[]
|
||||
[categoriasGlossario]
|
||||
);
|
||||
|
||||
const alfabeto = useMemo(() => {
|
||||
@@ -86,7 +96,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 +110,26 @@ export default function GlossarioPage() {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Glossário" }]}
|
||||
isEn={isEn}
|
||||
isEs={isEs}
|
||||
trail={[{ label: isEs ? "Glosario" : 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={isEs ? `${todosOsTermos.length} términos explicados` : isEn ? `${todosOsTermos.length} terms explained` : `${todosOsTermos.length} termos explicados`}
|
||||
title={isEs ? "Glosario técnico de ESP32" : isEn ? "ESP32 Technical Glossary" : "Glossário técnico do ESP32"}
|
||||
lede={
|
||||
isEs
|
||||
? "Definiciones directas, parámetros de hardware y un ejemplo práctico para cada término del ecosistema, desde ADC hasta Secure Boot."
|
||||
: 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={isEs ? "Búsqueda y filtros" : 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
|
||||
{isEs ? "Buscar término, sigla o concepto" : 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 +138,7 @@ export default function GlossarioPage() {
|
||||
type="search"
|
||||
value={busca}
|
||||
onChange={(e) => setBusca(e.target.value)}
|
||||
placeholder="Buscar termo, sigla ou conceito"
|
||||
placeholder={isEs ? "Buscar término, sigla o concepto" : 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 +146,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
|
||||
{isEs ? "Limpiar" : 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">{isEs ? "Más buscados" : 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 +166,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">{isEs ? "Categoría" : 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
|
||||
{isEs ? "Todas" : isEn ? "All" : "Todas"}
|
||||
<span className="tabular-nums opacity-80">{todosOsTermos.length}</span>
|
||||
</button>
|
||||
{categoriasGlossario.map((cat) => {
|
||||
@@ -176,10 +199,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">{isEs ? "Orden alfabético" : isEn ? "Alphabetical order" : "Ordem alfabética"}</h2>
|
||||
<div className="mt-3 flex flex-wrap gap-1.5" role="group" aria-label={isEs ? "Filtrar por letra inicial" : isEn ? "Filter by first letter" : "Filtrar pela letra inicial"}>
|
||||
<button type="button" onClick={() => setLetraFiltro(null)} aria-pressed={letraFiltro === null} className="chip-btn">
|
||||
Todas
|
||||
{isEs ? "Todas" : isEn ? "All" : "Todas"}
|
||||
</button>
|
||||
{alfabeto.map(({ letra, temTermos }) => (
|
||||
<button
|
||||
@@ -188,7 +211,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 +224,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 ? (isEs ? "término" : isEn ? "term" : "termo") : (isEs ? "términos" : isEn ? "terms" : "termos")}
|
||||
{temFiltroAtivo && <span className="font-normal text-muted">{isEs ? " con los filtros actuales" : 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
|
||||
{isEs ? "Restablecer filtros" : isEn ? "Reset filters" : "Redefinir filtros"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -215,13 +238,19 @@ 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">
|
||||
{isEs ? "No se encontraron términos" : 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.
|
||||
{isEs
|
||||
? "Nada coincide con la búsqueda y los filtros actuales. Pruebe con una sigla más corta o vuelva a todas las categorías."
|
||||
: 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
|
||||
{isEs ? "Limpiar filtros" : isEn ? "Clear filters" : "Limpar filtros"}
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
@@ -238,7 +267,7 @@ export default function GlossarioPage() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => copiarLinkTermo(item.slug)}
|
||||
aria-label={`Copiar link para ${item.termo}`}
|
||||
aria-label={isEs ? `Copiar enlace para ${item.termo}` : 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 +276,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
|
||||
{isEs ? "En la práctica" : 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 +297,23 @@ 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">
|
||||
{isEs ? "Del concepto al chip adecuado." : 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.
|
||||
{isEs
|
||||
? "Con los términos a mano, compare las series lado a lado o responda al selector para encontrar el modelo que se adapta a su proyecto."
|
||||
: 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
|
||||
{isEs ? "Elegir mi 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">
|
||||
{isEs ? "Explorar las series" : isEn ? "Explore series" : "Explorar as séries"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
@@ -294,7 +329,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 +355,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}
|
||||
|
||||
+70
-20
@@ -3,6 +3,7 @@ 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";
|
||||
@@ -38,11 +39,14 @@ const LANG_MAP = {
|
||||
};
|
||||
|
||||
export function generateStaticParams() {
|
||||
return routing.locales.map((locale) => ({ locale }));
|
||||
return ENABLED_LOCALES.map((locale) => ({ locale }));
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
|
||||
const ogLocaleMap = {
|
||||
pt: "pt_BR",
|
||||
en: "en_US",
|
||||
@@ -52,40 +56,86 @@ export async function generateMetadata({ params }) {
|
||||
"zh-CN": "zh_CN",
|
||||
};
|
||||
|
||||
const alternateLocales = ENABLED_LOCALES.filter((l) => l !== locale).map((l) => ogLocaleMap[l]);
|
||||
|
||||
const titleDefault = isEn
|
||||
? "ESPDocs · ESP32 Open Documentation"
|
||||
: isEs
|
||||
? "ESPDocs · Documentación abierta de ESP32"
|
||||
: "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."
|
||||
: isEs
|
||||
? "Especificaciones, patillaje, comparación y selección de las 12 series de microcontroladores ESP32. Hojas de datos, periféricos, seguridad en hardware y diagramas de conexión."
|
||||
: "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",
|
||||
]
|
||||
: isEs
|
||||
? [
|
||||
"ESP32", "ESP32 en español", "documentación ESP32", "patillaje ESP32", "pinout ESP32",
|
||||
"ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4", "ESP32-H2",
|
||||
"comparar ESP32", "cuál ESP32 elegir", "datasheet ESP32", "hoja de datos ESP32",
|
||||
"microcontrolador", "Espressif", "ESP-IDF", "IoT", "sistemas embebidos",
|
||||
]
|
||||
: [
|
||||
"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: "ESPDocs · Documentação do ESP32 em português",
|
||||
default: titleDefault,
|
||||
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.",
|
||||
description,
|
||||
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: `/${locale}` },
|
||||
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: "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.",
|
||||
title: titleDefault,
|
||||
description: isEn
|
||||
? "Specifications, pinouts, comparison and selection of 12 ESP32 microcontroller series."
|
||||
: isEs
|
||||
? "Especificaciones, patillaje, comparación y selección de las 12 series de microcontroladores ESP32."
|
||||
: "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.",
|
||||
title: titleDefault,
|
||||
description: isEn
|
||||
? "Specifications, pinouts, comparison and selection of 12 ESP32 series."
|
||||
: isEs
|
||||
? "Especificaciones, patillaje, comparación y selección de las 12 series de ESP32."
|
||||
: "Especificações, pinagem, comparação e seleção das 12 séries de ESP32, em português.",
|
||||
},
|
||||
robots: {
|
||||
index: true,
|
||||
@@ -127,7 +177,7 @@ export const viewport = {
|
||||
|
||||
export default async function RootLayout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
if (!routing.locales.includes(locale)) {
|
||||
if (!ENABLED_LOCALES.includes(locale)) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
@@ -141,7 +191,7 @@ export default async function RootLayout({ children, params }) {
|
||||
Google montar o box de busca interna e entender a autoria. */}
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.siteESociedade()) }}
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.siteESociedade(locale)) }}
|
||||
/>
|
||||
</head>
|
||||
<body className="font-sans antialiased bg-canvas text-ink overflow-x-clip" suppressHydrationWarning>
|
||||
@@ -149,7 +199,7 @@ export default async function RootLayout({ children, params }) {
|
||||
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
|
||||
{messages?.Common?.skipToContent || "Pular para o conteúdo"}
|
||||
</a>
|
||||
<NextIntlClientProvider locale={locale} messages={messages}>
|
||||
<Providers>
|
||||
|
||||
+54
-21
@@ -2,53 +2,86 @@ 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: "Página não encontrada",
|
||||
title: "404",
|
||||
robots: { index: false, follow: false },
|
||||
};
|
||||
|
||||
const CAMINHOS = [
|
||||
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." },
|
||||
];
|
||||
|
||||
export default function NotFound() {
|
||||
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." },
|
||||
];
|
||||
|
||||
const CAMINHOS_ES = [
|
||||
{ href: "/series", icon: Compass, titulo: "Series ESP32", texto: "Las 12 familias, con patillaje y especificaciones." },
|
||||
{ href: "/seletor", icon: SlidersHorizontal, titulo: "Selector de chip", texto: "Responda a ocho preguntas y reciba los modelos recomendados." },
|
||||
{ href: "/comparacao", icon: Scale, titulo: "Comparador", texto: "Hasta cuatro series frente a frente." },
|
||||
{ href: "/glossario", icon: BookOpen, titulo: "Glosario", texto: "Términos de hardware explicados con claridad." },
|
||||
];
|
||||
|
||||
export default async function NotFound() {
|
||||
let locale = "pt";
|
||||
try {
|
||||
locale = await getLocale();
|
||||
} catch {
|
||||
locale = "pt";
|
||||
}
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const caminhos = isEn ? CAMINHOS_EN : isEs ? CAMINHOS_ES : 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">Erro 404</p>
|
||||
<h1 className="page-title mt-4">Essa página não existe.</h1>
|
||||
<p className="eyebrow justify-center">{isEn ? "Error 404" : "Error 404"}</p>
|
||||
<h1 className="page-title mt-4">{isEn ? "This page does not exist." : isEs ? "Esta página no existe." : "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.
|
||||
{isEn
|
||||
? "The address may have changed or was mistyped. Choose one of these paths to continue."
|
||||
: isEs
|
||||
? "La dirección puede haber cambiado o estar mal escrita. Elija uno de estos caminos para continuar."
|
||||
: "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
|
||||
<Link href={isEn ? "/en" : isEs ? "/es" : "/"} className="btn btn-primary">
|
||||
{isEn ? "Back to home" : isEs ? "Volver al inicio" : "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>
|
||||
))}
|
||||
{caminhos.map(({ href, icon: Icon, titulo, texto }) => {
|
||||
const targetHref = getLocalizedHref(href, locale);
|
||||
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>
|
||||
|
||||
|
||||
+234
-41
@@ -2,10 +2,14 @@ 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 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 seriesDataEs from "@/data/es/series.json";
|
||||
import frameworksDataEs from "@/data/es/frameworks.json";
|
||||
import { SITE } from "@/lib/seo";
|
||||
import { getLocalizedHref } from "@/components/LanguageSelector";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
import {
|
||||
AlertTriangle,
|
||||
ArrowRight,
|
||||
@@ -20,7 +24,7 @@ import {
|
||||
|
||||
const FEATURED = ["ESP32", "ESP32-S3", "ESP32-C6", "ESP32-C3", "ESP32-P4", "ESP32-H2"];
|
||||
|
||||
const TOOLS = [
|
||||
const TOOLS_PT = [
|
||||
{
|
||||
href: "/seletor",
|
||||
title: "Seletor inteligente",
|
||||
@@ -65,7 +69,97 @@ const TOOLS = [
|
||||
},
|
||||
];
|
||||
|
||||
const ERRORS = [
|
||||
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 TOOLS_ES = [
|
||||
{
|
||||
href: "/seletor",
|
||||
title: "Selector inteligente",
|
||||
desc: "Responda a ocho preguntas sobre su proyecto y reciba los chips más compatibles, con justificación técnica.",
|
||||
icon: SlidersHorizontal,
|
||||
action: "Encontrar mi chip",
|
||||
},
|
||||
{
|
||||
href: "/comparacao",
|
||||
title: "Comparador de series",
|
||||
desc: "Compare hasta cuatro modelos frente a frente: núcleos, radio, memoria, periféricos y seguridad.",
|
||||
icon: Scale,
|
||||
action: "Comparar ahora",
|
||||
},
|
||||
{
|
||||
href: "/diagnostico",
|
||||
title: "Diagnóstico de fallos",
|
||||
desc: "Causas y soluciones para brownout, bootloop, Guru Meditation, watchdog y fallos de flash.",
|
||||
icon: AlertTriangle,
|
||||
action: "Abrir diagnóstico",
|
||||
},
|
||||
{
|
||||
href: "/componentes",
|
||||
title: "Component Registry",
|
||||
desc: "Drivers, bibliotecas y BSPs del registro oficial de Espressif, con manifiesto listo para su proyecto.",
|
||||
icon: Box,
|
||||
action: "Explorar componentes",
|
||||
},
|
||||
{
|
||||
href: "/frameworks",
|
||||
title: "Frameworks y SDKs",
|
||||
desc: "ESP-IDF, Arduino, Rust, Matter, MicroPython y las herramientas que rodean al silicio.",
|
||||
icon: Terminal,
|
||||
action: "Ver frameworks",
|
||||
},
|
||||
{
|
||||
href: "/catalogo",
|
||||
title: "Catálogo de placas",
|
||||
desc: "DevKits y módulos reales, con interfaz USB, sensores integrados y enlace directo a la tienda oficial.",
|
||||
icon: Cpu,
|
||||
action: "Ver placas",
|
||||
},
|
||||
];
|
||||
|
||||
const ERRORS_PT = [
|
||||
{
|
||||
code: "Brownout detector was triggered",
|
||||
cause: "Queda de tensão na inicialização do rádio.",
|
||||
@@ -88,11 +182,64 @@ const ERRORS = [
|
||||
},
|
||||
];
|
||||
|
||||
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.",
|
||||
},
|
||||
];
|
||||
|
||||
const ERRORS_ES = [
|
||||
{
|
||||
code: "Brownout detector was triggered",
|
||||
cause: "Caída de tensión al inicializar la etapa de radio.",
|
||||
fix: "Condensador de 10–100 µF junto al chip y fuente de 5 V con corriente suficiente.",
|
||||
},
|
||||
{
|
||||
code: "Guru Meditation Error",
|
||||
cause: "Puntero inválido, desbordamiento de pila o uso incorrecto de interrupciones.",
|
||||
fix: "Analice el backtrace con addr2line y dimensione la pila de la tarea en FreeRTOS.",
|
||||
},
|
||||
{
|
||||
code: "ADC2 no disponible con Wi-Fi",
|
||||
cause: "El controlador de radio reserva ADC2 mientras permanece activo.",
|
||||
fix: "Utilice los pines de ADC1 para sensores analógicos que funcionen junto con Wi-Fi.",
|
||||
},
|
||||
{
|
||||
code: "Flash Read err / bootloader",
|
||||
cause: "Tensión o modo de flash incorrectos, o pin de strapping forzado en el arranque.",
|
||||
fix: "Compruebe la línea de 3,3 V, los pull-ups de arranque y la configuración de flash en esptool.",
|
||||
},
|
||||
];
|
||||
|
||||
export default async function Home({ params }) {
|
||||
const { locale } = await params;
|
||||
const isPt = locale === "pt";
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const getLinkHref = (href) => getLocalizedHref(`/${locale}${href}`, locale);
|
||||
|
||||
const seriesData = isPt ? seriesDataPt : isEs ? seriesDataEs : seriesDataEn;
|
||||
const frameworksData = isPt ? frameworksDataPt : isEs ? frameworksDataEs : frameworksDataEn;
|
||||
const tools = isPt ? TOOLS_PT : isEs ? TOOLS_ES : TOOLS_EN;
|
||||
const errors = isPt ? ERRORS_PT : isEs ? ERRORS_ES : 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));
|
||||
@@ -106,39 +253,72 @@ export default async function Home({ params }) {
|
||||
<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
|
||||
{isPt ? "Documentação aberta do ESP32" : isEs ? "Documentación abierta de ESP32" : "Open ESP32 documentation"}
|
||||
</span>
|
||||
<h1 className="display mt-6 text-[clamp(2.9rem,7.4vw,5.4rem)]">
|
||||
O ESP32,
|
||||
<br className="sm:hidden" /> sem ruído.
|
||||
{isPt ? (
|
||||
<>
|
||||
O ESP32,
|
||||
<br className="sm:hidden" /> sem ruído.
|
||||
</>
|
||||
) : isEs ? (
|
||||
<>
|
||||
El ESP32,
|
||||
<br className="sm:hidden" /> sin ruido.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
The ESP32,
|
||||
<br className="sm:hidden" /> without noise.
|
||||
</>
|
||||
)}
|
||||
</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.
|
||||
{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."
|
||||
: isEs
|
||||
? "Especificaciones, patillaje, comparaciones y diagnóstico en una sola lectura. Menos traducción de hojas de datos, más tiempo con el prototipo en el banco de trabajo."
|
||||
: "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" />
|
||||
Escolher meu chip
|
||||
{isPt ? "Escolher meu chip" : isEs ? "Elegir mi chip" : "Choose my chip"}
|
||||
</Link>
|
||||
<Link href={getLinkHref("/series")} className="btn btn-ghost w-full sm:w-auto">
|
||||
Explorar as {seriesCount} séries
|
||||
{isPt ? (
|
||||
<>Explorar as {seriesCount} séries</>
|
||||
) : isEs ? (
|
||||
<>Explorar las {seriesCount} series</>
|
||||
) : (
|
||||
<>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> séries</span>
|
||||
<span><strong className="font-semibold text-ink">{seriesCount}</strong> {isPt ? "séries" : isEs ? "series" : "series"}</span>
|
||||
<span aria-hidden="true" className="text-line-strong">·</span>
|
||||
<span><strong className="font-semibold text-ink">{frameworkCount}</strong> frameworks</span>
|
||||
{isPt && (
|
||||
{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>
|
||||
</>
|
||||
) : isEs ? (
|
||||
<>
|
||||
<span aria-hidden="true" className="text-line-strong">·</span>
|
||||
<span>100% en español</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span aria-hidden="true" className="text-line-strong">·</span>
|
||||
<span>100% in English</span>
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
@@ -146,11 +326,13 @@ export default async function Home({ params }) {
|
||||
<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>
|
||||
<h2 className="text-sm font-semibold text-ink">{isPt ? "Séries em destaque" : isEs ? "Series destacadas" : "Featured series"}</h2>
|
||||
<p className="mt-0.5 text-xs text-muted">
|
||||
{isPt ? "O essencial de cada família, antes de abrir o datasheet." : isEs ? "Lo esencial de cada familia, antes de abrir la hoja de datos." : "The essentials of each family before opening the 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
|
||||
<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" : isEs ? "Índice completo" : "Full index"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
@@ -159,7 +341,7 @@ export default async function Home({ params }) {
|
||||
{featured.map(([key, serie]) => (
|
||||
<Link
|
||||
key={key}
|
||||
href={`/series/${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">
|
||||
@@ -175,7 +357,7 @@ export default async function Home({ params }) {
|
||||
<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
|
||||
{isPt ? "Ficha" : isEs ? "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>
|
||||
@@ -256,20 +438,24 @@ export default async function Home({ params }) {
|
||||
|
||||
<section className="shell section" aria-labelledby="ferramentas-titulo">
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<p className="eyebrow">Ferramentas</p>
|
||||
<p className="eyebrow">{isPt ? "Ferramentas" : isEs ? "Herramientas" : "Tools"}</p>
|
||||
<h2 id="ferramentas-titulo" className="display mt-4 text-[clamp(2rem,4.8vw,3.4rem)]">
|
||||
Comece pelo problema.
|
||||
{isPt ? "Comece pelo problema." : isEs ? "Empiece por el problema." : "Start with the problem."}
|
||||
</h2>
|
||||
<p className="lede mt-4">
|
||||
Cada ferramenta resolve uma etapa concreta do projeto, sem cadastro e sem rodeio.
|
||||
{isPt
|
||||
? "Cada ferramenta resolve uma etapa concreta do projeto, sem cadastro e sem rodeio."
|
||||
: isEs
|
||||
? "Cada herramienta resuelve una fase concreta del proyecto, sin registros ni rodeos."
|
||||
: "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) => {
|
||||
{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">
|
||||
<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>
|
||||
@@ -288,16 +474,20 @@ export default async function Home({ params }) {
|
||||
<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>
|
||||
<p className="eyebrow">{isPt ? "Diagnóstico" : isEs ? "Diagnóstico" : "Diagnostics"}</p>
|
||||
<h2 id="diagnostico-titulo" className="display mt-4 text-[clamp(2rem,4.8vw,3.4rem)]">
|
||||
O primeiro boot não precisa virar noite.
|
||||
{isPt ? "O primeiro boot não precisa virar noite." : isEs ? "El primer arranque no tiene por qué desvelarlo." : "First boot doesn't have to take all night."}
|
||||
</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.
|
||||
{isPt
|
||||
? "Os erros mais comuns têm causa conhecida. O guia parte da mensagem no terminal e chega ao ajuste de hardware ou firmware."
|
||||
: isEs
|
||||
? "Los errores más comunes tienen una causa conocida. Esta guía parte del mensaje en el terminal y llega al ajuste de hardware o 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="/diagnostico" className="btn btn-accent mt-7">
|
||||
<Link href={getLinkHref("/diagnostico")} className="btn btn-accent mt-7">
|
||||
<AlertTriangle className="h-4 w-4" aria-hidden="true" />
|
||||
Abrir os 30+ diagnósticos
|
||||
{isPt ? "Abrir os 30+ diagnósticos" : isEs ? "Abrir los 30+ diagnósticos" : "Open the 30+ diagnostics"}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -307,11 +497,11 @@ export default async function Home({ params }) {
|
||||
<Terminal className="h-4 w-4" aria-hidden="true" />
|
||||
boot.log
|
||||
</span>
|
||||
<span className="text-xs text-[#a6afbd]">4 exemplos de 30+</span>
|
||||
<span className="text-xs text-[#a6afbd]">{isPt ? "4 exemplos de 30+" : isEs ? "4 ejemplos de 30+" : "4 examples of 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">
|
||||
{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>
|
||||
@@ -324,21 +514,24 @@ export default async function Home({ params }) {
|
||||
|
||||
<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>
|
||||
<p className="eyebrow">{isPt ? "Curadoria independente" : isEs ? "Curaduría independiente" : "Independent curation"}</p>
|
||||
<h2 className="display mt-4 text-[clamp(2rem,4.5vw,3.2rem)]">
|
||||
Feito para consultar no meio do projeto.
|
||||
{isPt ? "Feito para consultar no meio do projeto." : isEs ? "Diseñado para consultar en mitad del proyecto." : "Built for quick lookup mid-project."}
|
||||
</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.
|
||||
{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."
|
||||
: isEs
|
||||
? "ESPDocs organiza datos públicos de Espressif y apunta siempre a la fuente oficial. Para decisiones críticas, la hoja de datos y el Technical Reference Manual continúan teniendo la última palabra."
|
||||
: "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="/glossario" className="btn btn-ghost w-full sm:w-auto">
|
||||
<Link href={getLinkHref("/glossario")} className="btn btn-ghost w-full sm:w-auto">
|
||||
<BookOpen className="h-4 w-4" aria-hidden="true" />
|
||||
Glossário
|
||||
{isPt ? "Glossário" : isEs ? "Glosario" : "Glossary"}
|
||||
</Link>
|
||||
<Link href="/sobre" className="btn btn-primary w-full sm:w-auto">
|
||||
Sobre o projeto
|
||||
<Link href={getLinkHref("/sobre")} className="btn btn-primary w-full sm:w-auto">
|
||||
{isPt ? "Sobre o projeto" : isEs ? "Acerca del proyecto" : "About the project"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,27 @@
|
||||
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"],
|
||||
});
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
return paginaMeta({
|
||||
titulo: isEs ? "Qué ESP32 elegir" : isEn ? "Which ESP32 to Choose" : "Qual ESP32 escolher",
|
||||
descricao: isEs
|
||||
? "Responda a preguntas sencillas sobre conectividad (Wi-Fi 6, 5GHz, Matter), energía, periféricos y seguridad o use el filtro paramétrico para encontrar el ESP32 perfecto."
|
||||
: 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: isEs
|
||||
? ["qué ESP32 elegir", "cuál ESP32 usar", "elegir microcontrolador", "ESP32 para mi proyecto", "comparar ESP32"]
|
||||
: 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 faqs = [
|
||||
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.",
|
||||
@@ -26,7 +40,50 @@ const faqs = [
|
||||
},
|
||||
];
|
||||
|
||||
export default function Layout({ children }) {
|
||||
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.",
|
||||
},
|
||||
];
|
||||
|
||||
const faqsEs = [
|
||||
{
|
||||
pergunta: "¿Cuál ESP32 elegir para principiantes?",
|
||||
resposta: "Para quienes se inician en el mundo Maker e IoT, el ESP32 clásico (NodeMCU/DevKitC) o el ESP32-C3 son las mejores opciones gracias al amplio soporte de bibliotecas, ejemplos listos en Arduino IDE y abundante documentación.",
|
||||
},
|
||||
{
|
||||
pergunta: "¿Cuál ESP32 soporta Wi-Fi 6, Bluetooth 6 y Thread/Zigbee/Matter?",
|
||||
resposta: "El ESP32-C6 y el ESP32-C5 son las series destacadas para redes modernas. El ESP32-C6 ofrece Wi-Fi 6 (2.4 GHz) y radio 802.15.4 (Zigbee 3.0 / Thread / Matter). El ESP32-C5 es el primero en ofrecer soporte para Wi-Fi 6 de doble banda operando en 2.4 GHz y 5 GHz simultáneamente.",
|
||||
},
|
||||
{
|
||||
pergunta: "¿Cuál es el ESP32 más potente para Inteligencia Artificial (TinyML) y Pantallas?",
|
||||
resposta: "El ESP32-P4 (dual-core RISC-V a 400 MHz con extensiones vectoriales de IA, interfaces MIPI-CSI/DSI para cámaras/pantallas y hasta 64 MB de PSRAM) y el ESP32-S3 (dual-core Xtensa a 240 MHz con aceleradores vectoriales para redes neuronales y soporte para LCD RGB) son los más rápidos para IA en el borde e interfaces gráficas avanzadas.",
|
||||
},
|
||||
{
|
||||
pergunta: "¿Cuál ESP32 consume menos energía para proyectos a batería?",
|
||||
resposta: "Los microcontroladores con arquitectura RISC-V compacta y coprocesador ULP, como el ESP32-C2, ESP32-C3 y ESP32-H2 (dedicado a 802.15.4 sin radio Wi-Fi), ofrecen corrientes de deep sleep extremadamente bajas (en el rango de 5 µA a 10 µA).",
|
||||
},
|
||||
];
|
||||
|
||||
export default async function Layout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const faqs = isEs ? faqsEs : isEn ? faqsEn : faqsPt;
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
@@ -34,9 +91,14 @@ export default function Layout({ children }) {
|
||||
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",
|
||||
nome: isEs ? "Selector Inteligente de ESP32" : isEn ? "Intelligent ESP32 Selector" : "Seletor Inteligente de ESP32",
|
||||
descricao: isEs
|
||||
? "Herramienta interactiva que analiza conectividad, consumo, periféricos y seguridad para recomendar la serie ideal de ESP32."
|
||||
: 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: isEs ? "/es/selector" : isEn ? "/en/selector" : "/seletor",
|
||||
locale,
|
||||
})
|
||||
),
|
||||
}}
|
||||
@@ -46,8 +108,8 @@ export default function Layout({ children }) {
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Seletor de ESP32", caminho: "/seletor" },
|
||||
{ nome: isEs ? "Inicio" : isEn ? "Home" : "Início", caminho: isEs ? "/es" : isEn ? "/en" : "/" },
|
||||
{ nome: isEs ? "Selector de ESP32" : isEn ? "ESP32 Selector" : "Seletor de ESP32", caminho: isEs ? "/es/selector" : isEn ? "/en/selector" : "/seletor" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
|
||||
+906
-305
File diff suppressed because it is too large.
Load diff
+434
-173
@@ -5,10 +5,13 @@ 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 seriesDataPt from "@/public/series.json";
|
||||
import seriesDataEn from "@/data/en/series.json";
|
||||
import seriesDataEs from "@/data/es/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,
|
||||
@@ -31,7 +34,11 @@ import {
|
||||
} from "lucide-react";
|
||||
|
||||
export default async function SerieDetail({ params }) {
|
||||
const { key } = await params;
|
||||
const { locale, key } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : "pt";
|
||||
const seriesData = isEs ? seriesDataEs : isEn ? seriesDataEn : seriesDataPt;
|
||||
const serie = seriesData[key];
|
||||
|
||||
if (!serie) {
|
||||
@@ -40,7 +47,11 @@ export default async function SerieDetail({ params }) {
|
||||
|
||||
let conexoes = [];
|
||||
try {
|
||||
conexoes = require(`@/public/conexoes/${key}.json`);
|
||||
conexoes = isEs
|
||||
? require(`@/data/es/conexoes/${key}.json`)
|
||||
: 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}`);
|
||||
}
|
||||
@@ -50,98 +61,252 @@ export default async function SerieDetail({ params }) {
|
||||
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 nao = isEs || isEn ? "No" : "Não";
|
||||
const naoInformado = isEs ? "No informado" : isEn ? "Not informed" : "Não informado";
|
||||
|
||||
const processadorSpecs = isEs
|
||||
? [
|
||||
{ label: "Arquitectura", value: serie.arquitetura },
|
||||
{ label: "Núcleos", value: serie.nucleos },
|
||||
{ label: "Frecuencia", value: serie.frequencia },
|
||||
{ label: "Coprocesador ULP", value: serie.coprocessador_ulp || nao },
|
||||
{ label: "Aceleradores de IA", value: serie.aceleradores_ia || nao },
|
||||
]
|
||||
: 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 = [
|
||||
{ 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 segurancaSpecs = isEs
|
||||
? [
|
||||
{ label: "AES", value: seg.aes || nao },
|
||||
{ label: "SHA", value: seg.sha || nao },
|
||||
{ label: "RSA / MPI", value: seg.rsa || nao },
|
||||
{ label: "ECC (curvas elípticas)", value: seg.ecc || nao },
|
||||
{ label: "ECDSA en hardware", value: seg.ecdsa || nao },
|
||||
{ label: "HMAC", value: seg.hmac || nao },
|
||||
{ label: "Firma digital (DS)", value: seg.assinatura_digital || nao },
|
||||
{ label: "Key Manager", value: seg.key_manager || nao },
|
||||
{ label: "Generador aleatorio (TRNG)", value: seg.rng || nao },
|
||||
{ label: "Cifrado de flash", value: seg.criptografia_flash || nao },
|
||||
{ label: "Secure Boot", value: seg.secure_boot || nao },
|
||||
{ label: "Protección contra DPA", value: seg.protecao_dpa || nao },
|
||||
]
|
||||
: 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 = [
|
||||
{ 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 ferramentasSpecs = isEs
|
||||
? [
|
||||
{ label: "ESP-IDF mínimo", value: serie.esp_idf_minimo || naoInformado },
|
||||
{ label: "Core Arduino", value: serie.arduino_core || naoInformado },
|
||||
{ label: "Depuración", value: serie.depuracao || naoInformado },
|
||||
{ label: "Encapsulado", value: serie.encapsulamento || naoInformado },
|
||||
{ label: "Módulos disponibles", value: serie.modulos || naoInformado },
|
||||
]
|
||||
: 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 = [
|
||||
{ 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 conectividadeSpecs = isEs
|
||||
? [
|
||||
{ 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 },
|
||||
]
|
||||
: 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 = [
|
||||
{ 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 memoriaSpecs = isEs
|
||||
? [
|
||||
{ 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 || nao },
|
||||
]
|
||||
: 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 = [
|
||||
{ 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 perifericos = isEs
|
||||
? [
|
||||
{ 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 },
|
||||
]
|
||||
: 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: "Câmera", value: serie.camera });
|
||||
if (serie.camera) interfacesEspeciais.push({ label: isEs ? "Cámara" : 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: "Sensor Hall", value: serie.sensor_hall });
|
||||
if (serie.sensor_temperatura) interfacesEspeciais.push({ label: "Sensor Temperatura", value: serie.sensor_temperatura });
|
||||
if (serie.sensor_hall) interfacesEspeciais.push({ label: isEs ? "Sensor Hall" : isEn ? "Hall Sensor" : "Sensor Hall", value: serie.sensor_hall });
|
||||
if (serie.sensor_temperatura) interfacesEspeciais.push({ label: isEs ? "Sensor de temperatura" : isEn ? "Temperature Sensor" : "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'
|
||||
};
|
||||
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 modoLabelsEs = {
|
||||
'active': 'Modo activo',
|
||||
'active_cpu_240mhz': 'Activo (CPU 240MHz)',
|
||||
'active_cpu_160mhz': 'Activo (CPU 160MHz)',
|
||||
'active_wifi_tx': 'Activo (Wi-Fi TX)',
|
||||
'active_wifi_tx_peak': 'Activo (Wi-Fi TX Pico)',
|
||||
'active_wifi': 'Activo (Wi-Fi)',
|
||||
'active_wifi6': 'Activo (Wi-Fi 6)',
|
||||
'modem_sleep': 'Modem Sleep',
|
||||
'modem_sleep_cpu_160mhz': 'Modem Sleep (CPU 160MHz)',
|
||||
'light_sleep': 'Light Sleep',
|
||||
'deep_sleep': 'Deep Sleep',
|
||||
'hibernation': 'Hibernación'
|
||||
};
|
||||
const modoLabels = isEs ? modoLabelsEs : 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()),
|
||||
label: modoLabels[modo] || modo.replace(/_/g, ' ').replace(/\b\w/g, (l) => l.toUpperCase()),
|
||||
value: consumo
|
||||
});
|
||||
});
|
||||
@@ -150,38 +315,58 @@ export default async function SerieDetail({ params }) {
|
||||
const tabs = [
|
||||
{
|
||||
id: "devboard",
|
||||
label: "Placa de desenvolvimento",
|
||||
label: isEs ? "Placa de desarrollo" : 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">Kit de desenvolvimento oficial</h2>
|
||||
<h2 className="text-lg font-semibold text-ink">
|
||||
{isEs ? "Kit de desarrollo oficial" : 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={`Placa de desenvolvimento ${key}`}
|
||||
alt={isEs ? `Placa de desarrollo ${key}` : 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">Placa padrão da Espressif para a série {key}.</p>
|
||||
<p className="mt-3 text-sm text-muted">
|
||||
{isEs ? (
|
||||
<>Placa estándar de Espressif para la serie {key}.</>
|
||||
) : isEn ? (
|
||||
<>Official Espressif board for the {key} series.</>
|
||||
) : (
|
||||
<>Placa padrão da Espressif para a série {key}.</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "connections",
|
||||
label: "Diagrama de conexões",
|
||||
label: isEs ? "Diagrama de patillaje" : 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">Este é o diagrama do chip, não da placa</p>
|
||||
<p className="font-semibold text-ink">
|
||||
{isEs ? "Este es el diagrama del chip, no de la placa" : isEn ? "This is the chip diagram, not the development board" : "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.
|
||||
{isEs ? (
|
||||
`El mapa muestra las conexiones del silicio del ${key}. Cada placa de desarrollo expone solo parte de ellas o las enruta de otra forma.`
|
||||
) : 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>
|
||||
@@ -193,22 +378,57 @@ export default async function SerieDetail({ params }) {
|
||||
<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
|
||||
{isEs ? "Casi todos los pines son reconfigurables" : isEn ? "Almost every pin is reconfigurable" : "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>
|
||||
.
|
||||
{isEs ? (
|
||||
<>
|
||||
La matriz de E/S del {key} permite mover buses SPI, I2C, UART, PWM y cámara/pantalla
|
||||
a la mayoría de los pines digitales. Para las restricciones de strapping y pines analógicos,
|
||||
consulte la{" "}
|
||||
<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"
|
||||
>
|
||||
guía oficial de GPIO
|
||||
<ExternalLink className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
</a>
|
||||
.
|
||||
</>
|
||||
) : 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>
|
||||
@@ -217,55 +437,59 @@ export default async function SerieDetail({ params }) {
|
||||
];
|
||||
|
||||
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 },
|
||||
{ id: "processador", titulo: isEs ? "Procesador" : isEn ? "Processor" : "Processador", icon: Cpu, specs: processadorSpecs },
|
||||
{ id: "conectividade", titulo: isEs ? "Conectividad" : isEn ? "Connectivity" : "Conectividade", icon: Wifi, specs: conectividadeSpecs },
|
||||
{ id: "ferramentas", titulo: isEs ? "Herramientas y disponibilidad" : isEn ? "Tools and availability" : "Ferramentas e disponibilidade", icon: Package, specs: ferramentasSpecs },
|
||||
{ id: "seguranca", titulo: isEs ? "Seguridad" : isEn ? "Security" : "Segurança", icon: ShieldCheck, specs: segurancaSpecs },
|
||||
{ id: "memoria", titulo: isEs ? "Memoria" : isEn ? "Memory" : "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: "energia",
|
||||
titulo: isEs ? "Consumo de energía" : isEn ? "Power consumption" : "Consumo de energia",
|
||||
icon: Battery,
|
||||
specs: consumoEnergia,
|
||||
nota: isEs
|
||||
? "Valores típicos a 3,3 V y 25 °C. El consumo real depende del ciclo de trabajo de la radio y de la frecuencia de reloj configurada."
|
||||
: 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: "Periféricos", icon: Sliders, specs: perifericos },
|
||||
{ id: "perifericos", titulo: isEs ? "Periféricos" : isEn ? "Peripherals" : "Periféricos", icon: Sliders, specs: perifericos },
|
||||
...(interfacesEspeciais.length > 0
|
||||
? [{ id: "interfaces", titulo: "Interfaces especiais", icon: Sliders, specs: interfacesEspeciais }]
|
||||
? [{ id: "interfaces", titulo: isEs ? "Interfaces especiales" : isEn ? "Special interfaces" : "Interfaces especiais", icon: Sliders, specs: interfacesEspeciais }]
|
||||
: []),
|
||||
{
|
||||
id: "temperatura",
|
||||
titulo: "Limites de temperatura",
|
||||
titulo: isEs ? "Límites de temperatura" : isEn ? "Temperature limits" : "Limites de temperatura",
|
||||
icon: Thermometer,
|
||||
specs: [
|
||||
{ label: "Operação", value: serie.temperatura_operacao },
|
||||
{ label: "Armazenamento", value: serie.temperatura_armazenamento },
|
||||
{ label: isEs ? "Operación" : isEn ? "Operating" : "Operação", value: serie.temperatura_operacao },
|
||||
{ label: isEs ? "Almacenamiento" : isEn ? "Storage" : "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 },
|
||||
{ label: isEs ? "Procesador" : isEn ? "Processor" : "Processador", value: String(serie.nucleos).includes("2") ? "Dual-core" : "Single-core", detail: serie.frequencia },
|
||||
{ label: "SRAM", value: serie.memoria_sram, detail: isEs ? `+ ${serie.memoria_sram_rtc} de SRAM RTC` : isEn ? `+ ${serie.memoria_sram_rtc} RTC SRAM` : `+ ${serie.memoria_sram_rtc} de SRAM RTC` },
|
||||
{ label: "GPIO", value: serie.gpio, detail: isEs ? "pines programables" : isEn ? "programmable pins" : "pinos programáveis" },
|
||||
{ label: isEs ? "Arquitectura" : 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)) }}
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.serie(key, serie, currentLocale)) }}
|
||||
/>
|
||||
<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}` },
|
||||
{ nome: isEs ? "Inicio" : isEn ? "Home" : "Início", caminho: isEn ? "/en" : isEs ? "/es" : "/" },
|
||||
{ nome: isEs ? "Series" : isEn ? "Series" : "Séries", caminho: getLocalizedHref("/series", currentLocale) },
|
||||
{ nome: serie.nome_completo, caminho: getLocalizedHref(`/series/${key}`, currentLocale) },
|
||||
])),
|
||||
}}
|
||||
/>
|
||||
@@ -274,7 +498,9 @@ export default async function SerieDetail({ params }) {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Séries", href: "/series" }, { label: key }]}
|
||||
isEn={isEn}
|
||||
isEs={isEs}
|
||||
trail={[{ label: isEs ? "Series" : isEn ? "Series" : "Séries", href: getLocalizedHref("/series", currentLocale) }, { label: key }]}
|
||||
icon={Cpu}
|
||||
label={serie.arquitetura}
|
||||
title={key}
|
||||
@@ -283,32 +509,32 @@ export default async function SerieDetail({ params }) {
|
||||
{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
|
||||
{isEs ? "Datasheet oficial" : 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" />
|
||||
Datasheet ainda não publicado
|
||||
{isEs ? "Datasheet aún no publicado" : 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" />
|
||||
Guia de programação
|
||||
{isEs ? "Guía de programación" : 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" />
|
||||
Manual técnico
|
||||
{isEs ? "Manual de referencia técnica" : 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="Resumo">
|
||||
<section className="shell mt-10" aria-label={isEs ? "Resumen" : isEn ? "Summary" : "Resumo"}>
|
||||
<dl className="grid grid-cols-2 gap-3 lg:grid-cols-4">
|
||||
{fatos.map((fato) => (
|
||||
<div key={fato.label} className="tile">
|
||||
@@ -323,7 +549,9 @@ export default async function SerieDetail({ params }) {
|
||||
<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="font-semibold text-ink">
|
||||
{isEs ? "Documentación preliminar" : isEn ? "Preliminary documentation" : "Documentação preliminar"}
|
||||
</p>
|
||||
<p className="mt-1">{serie.status_documentacao}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -331,13 +559,13 @@ export default async function SerieDetail({ params }) {
|
||||
</section>
|
||||
|
||||
<div className="shell mt-10">
|
||||
<SeriesTabMenu tabs={tabs} />
|
||||
<PinRestrictions conexoes={conexoes} serieKey={key} />
|
||||
<SeriesTabMenu tabs={tabs} isEn={isEn} isEs={isEs} />
|
||||
<PinRestrictions conexoes={conexoes} serieKey={key} isEn={isEn} isEs={isEs} />
|
||||
</div>
|
||||
|
||||
<div className="shell mt-12">
|
||||
<nav
|
||||
aria-label="Seções da ficha"
|
||||
aria-label={isEs ? "Secciones de la ficha" : 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) => (
|
||||
@@ -357,37 +585,49 @@ export default async function SerieDetail({ params }) {
|
||||
<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>
|
||||
<h2 className="section-title">
|
||||
{isEs ? (
|
||||
<>¿Listo para prototipar con {key}?</>
|
||||
) : isEn ? (
|
||||
<>Ready to prototype with {key}?</>
|
||||
) : (
|
||||
<>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.
|
||||
{isEs
|
||||
? "Explore las placas de desarrollo disponibles para esta serie, con USB, sensores integrados y enlaces a la tienda oficial."
|
||||
: 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="/catalogo" className="btn btn-primary shrink-0">
|
||||
Ver placas
|
||||
<Link href={getLocalizedHref("/catalogo", currentLocale)} className="btn btn-primary shrink-0">
|
||||
{isEs ? "Ver placas" : isEn ? "View boards" : "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">
|
||||
<nav aria-label={isEs ? "Otras series" : isEn ? "Other series" : "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">
|
||||
<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">Série anterior</span>
|
||||
<span className="block text-xs text-muted">{isEs ? "Serie anterior" : 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="/comparacao" className="btn btn-ghost justify-self-center">
|
||||
<Link href={getLocalizedHref("/comparacao", currentLocale)} className="btn btn-ghost justify-self-center">
|
||||
<Scale className="h-4 w-4" aria-hidden="true" />
|
||||
Comparar séries
|
||||
{isEs ? "Comparar series" : isEn ? "Compare series" : "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">
|
||||
<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">Próxima série</span>
|
||||
<span className="block text-xs text-muted">{isEs ? "Siguiente serie" : 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" />
|
||||
@@ -416,7 +656,7 @@ function SpecSection({ id, titulo, icon: Icon, specs, nota }) {
|
||||
{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));
|
||||
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>
|
||||
@@ -430,49 +670,70 @@ function SpecSection({ id, titulo, icon: Icon, specs, nota }) {
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { key } = await params;
|
||||
const { locale, key } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : "pt";
|
||||
const seriesData = isEs ? seriesDataEs : isEn ? seriesDataEn : seriesDataPt;
|
||||
const serie = seriesData[key];
|
||||
|
||||
if (!serie) {
|
||||
return { title: "Série não encontrada", robots: { index: false, follow: false } };
|
||||
return { title: isEs ? "Serie no encontrada" : isEn ? "Series not found" : "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,
|
||||
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 =
|
||||
`${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 descricao = isEs
|
||||
? `${serie.nome_completo}: ${serie.arquitetura}, ${serie.frequencia}, ` +
|
||||
`${serie.memoria_sram} de SRAM y ${serie.gpio} GPIO` +
|
||||
(radio ? `. Radio: ${radio}` : "") +
|
||||
`. Patillaje completo, periféricos, seguridad por hardware y pines restringidos, en español.`
|
||||
: 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.`;
|
||||
|
||||
// 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: serie.placa, width: 1600, height: 1091, alt: isEs ? `Patillaje de ${serie.nome_completo}` : isEn ? `Pinout of ${serie.nome_completo}` : `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: [
|
||||
const keywords = isEs
|
||||
? [
|
||||
serie.nome_completo, `${serie.nome_completo} pinout`, `${serie.nome_completo} patillaje`,
|
||||
`${serie.nome_completo} datasheet`, `${serie.nome_completo} especificaciones`,
|
||||
`${serie.nome_completo} español`, "ESP32", "Espressif", "microcontrolador",
|
||||
]
|
||||
: 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: isEs ? `${serie.nome_completo}: especificaciones y patillaje` : 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": "Séries ESP32" },
|
||||
other: { "article:section": isEs ? "Series ESP32" : isEn ? "ESP32 Series" : "Séries ESP32" },
|
||||
};
|
||||
|
||||
meta.openGraph = { ...meta.openGraph, images: imagem };
|
||||
@@ -482,7 +743,7 @@ export async function generateMetadata({ params }) {
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return Object.keys(seriesData).map((key) => ({
|
||||
return Object.keys(seriesDataPt).map((key) => ({
|
||||
key: key,
|
||||
}));
|
||||
}
|
||||
@@ -1,15 +1,32 @@
|
||||
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"],
|
||||
});
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const meta = paginaMeta({
|
||||
titulo: isEs ? "Series ESP32: Guía técnica y patillaje" : isEn ? "ESP32 Series: Technical Guide and Pinouts" : "Séries ESP32",
|
||||
descricao: isEs
|
||||
? "Las 12 series de ESP32 lado a lado: ESP32, S2, S3, S31, C2, C3, C5, C6, C61, P4, H2 y H4. Arquitectura, memoria, radio, periféricos y patillaje de cada una."
|
||||
: 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: isEs
|
||||
? ["series ESP32", "modelos de ESP32", "ESP32 S3", "ESP32 C6", "ESP32 P4", "diferencia entre ESP32"]
|
||||
: 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: isEs ? "Series ESP32" : isEn ? "ESP32 Series" : "Séries ESP32",
|
||||
template: "%s · ESPDocs",
|
||||
};
|
||||
return meta;
|
||||
}
|
||||
|
||||
metadata.title = { default: "Séries ESP32", template: "%s · ESPDocs" };
|
||||
|
||||
const faqs = [
|
||||
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.",
|
||||
@@ -20,7 +37,34 @@ const faqs = [
|
||||
},
|
||||
];
|
||||
|
||||
export default function Layout({ children }) {
|
||||
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).",
|
||||
},
|
||||
];
|
||||
|
||||
const faqsEs = [
|
||||
{
|
||||
pergunta: "¿Cuántas series de ESP32 existen actualmente?",
|
||||
resposta: "Actualmente, el ecosistema de Espressif cuenta con 12 series principales: ESP32 clásico, ESP32-S2, ESP32-S3, ESP32-S31, ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-P4, ESP32-H2 y ESP32-H4.",
|
||||
},
|
||||
{
|
||||
pergunta: "¿Cuáles son las series más recientes de Espressif?",
|
||||
resposta: "Las series más recientes incluyen el ESP32-P4 (enfocado en alto rendimiento con dual-core RISC-V a 400 MHz), el ESP32-C5 (primer chip con Wi-Fi de doble banda 2.4/5 GHz de Espressif) y el ESP32-C61 (Wi-Fi 6 y Bluetooth 6 de bajo costo).",
|
||||
},
|
||||
];
|
||||
|
||||
export default async function Layout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const faqs = isEs ? faqsEs : isEn ? faqsEn : faqsPt;
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
@@ -28,8 +72,8 @@ export default function Layout({ children }) {
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Séries ESP32", caminho: "/series" },
|
||||
{ nome: isEs ? "Inicio" : isEn ? "Home" : "Início", caminho: isEs ? "/es" : isEn ? "/en" : "/" },
|
||||
{ nome: isEs ? "Series ESP32" : isEn ? "ESP32 Series" : "Séries ESP32", caminho: isEs ? "/es/series" : isEn ? "/en/series" : "/series" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
|
||||
+102
-37
@@ -1,11 +1,15 @@
|
||||
"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 seriesData from "@/public/series.json";
|
||||
import seriesDataPt from "@/public/series.json";
|
||||
import seriesDataEn from "@/data/en/series.json";
|
||||
import seriesDataEs from "@/data/es/series.json";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
import {
|
||||
AlertTriangle,
|
||||
ArrowRight,
|
||||
@@ -17,7 +21,7 @@ import {
|
||||
Sparkles,
|
||||
} from "lucide-react";
|
||||
|
||||
const FILTROS = [
|
||||
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") },
|
||||
@@ -25,22 +29,51 @@ const FILTROS = [
|
||||
{ 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) },
|
||||
];
|
||||
|
||||
const FILTROS_ES = [
|
||||
{ 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 === "Yes" || s.matter === "Sim" || s.matter === "Sí" },
|
||||
{ id: "ia", rotulo: "Aceleración 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) {
|
||||
function nivelSeguranca(serie, isEn, isEs) {
|
||||
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 (seg.key_manager === "Sim" || seg.key_manager === "Yes" || seg.key_manager === "Sí") return "Key Manager";
|
||||
if (String(seg.ecdsa).startsWith("Sim") || String(seg.ecdsa).startsWith("Yes") || String(seg.ecdsa).startsWith("Sí")) {
|
||||
return isEs ? "ECDSA en hardware" : isEn ? "Hardware ECDSA" : "ECDSA em hardware";
|
||||
}
|
||||
if (String(seg.ecc).startsWith("Sim") || String(seg.ecc).startsWith("Yes") || String(seg.ecc).startsWith("Sí")) {
|
||||
return isEs ? "ECC en hardware" : isEn ? "Hardware ECC" : "ECC em hardware";
|
||||
}
|
||||
if (String(seg.aes).startsWith("AES")) return "AES + SHA";
|
||||
return "Só SHA";
|
||||
return isEs ? "Solo SHA" : isEn ? "SHA only" : "Só SHA";
|
||||
}
|
||||
|
||||
const sim = (v) => !String(v).includes("Não");
|
||||
const simPt = (v) => !String(v).includes("Não");
|
||||
const simEn = (v) => !String(v).includes("No") && !String(v).includes("Não");
|
||||
const simEs = (v) => !String(v).includes("No") && !String(v).includes("Não");
|
||||
|
||||
export default function Series() {
|
||||
const pathname = usePathname();
|
||||
const isEn = pathname?.startsWith("/en");
|
||||
const isEs = pathname?.startsWith("/es");
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : "pt";
|
||||
const seriesData = isEs ? seriesDataEs : isEn ? seriesDataEn : seriesDataPt;
|
||||
const filtros = isEs ? FILTROS_ES : isEn ? FILTROS_EN : FILTROS_PT;
|
||||
|
||||
const [filtro, setFiltro] = useState("todas");
|
||||
const todas = Object.entries(seriesData);
|
||||
const ativo = FILTROS.find((f) => f.id === filtro);
|
||||
const ativo = filtros.find((f) => f.id === filtro) || filtros[0];
|
||||
const series = useMemo(() => todas.filter(([, s]) => ativo.testa(s)), [todas, ativo]);
|
||||
|
||||
return (
|
||||
@@ -49,40 +82,66 @@ export default function Series() {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Séries" }]}
|
||||
isEn={isEn}
|
||||
isEs={isEs}
|
||||
trail={[{ label: isEs ? "Series" : isEn ? "Series" : "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."
|
||||
label={isEs ? `${todas.length} familias de Espressif` : isEn ? `${todas.length} Espressif families` : `${todas.length} famílias da Espressif`}
|
||||
title={isEs ? "Series ESP32" : isEn ? "ESP32 Series" : "Séries ESP32"}
|
||||
lede={
|
||||
isEs
|
||||
? "Cada serie fue diseñada para un tipo de proyecto específico, desde sensores a batería hasta aceleradores de IA. Abra la ficha para ver patillaje, periféricos y seguridad."
|
||||
: 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="Lista de séries">
|
||||
<div role="group" aria-label="Filtrar séries" className="flex flex-wrap gap-2">
|
||||
{FILTROS.map((f) => (
|
||||
<section className="shell pt-10 sm:pt-12" aria-label={isEs ? "Lista de series" : isEn ? "Series list" : "Lista de séries"}>
|
||||
<div role="group" aria-label={isEs ? "Filtrar series" : 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 ? "série" : "séries"}
|
||||
{series.length} {series.length === 1 ? (isEs ? "serie" : isEn ? "series" : "série") : (isEs ? "series" : 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 = [
|
||||
["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);
|
||||
const fatos = isEs
|
||||
? [
|
||||
["Núcleos", serie.nucleos],
|
||||
["Frecuencia", serie.frequencia],
|
||||
["SRAM", serie.memoria_sram],
|
||||
["Wi-Fi", simEs(serie.wifi) ? "Sí" : "No"],
|
||||
["Bluetooth", String(serie.bluetooth).includes("No") || String(serie.bluetooth).includes("Não") ? "No" : "Sí"],
|
||||
serie.consumo_energia?.deep_sleep ? ["Deep sleep", serie.consumo_energia.deep_sleep] : null,
|
||||
].filter(Boolean)
|
||||
: 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={`/series/${key}`} className="card card-interactive group flex flex-col p-5 sm:p-6">
|
||||
<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.035em] text-ink">{key}</h2>
|
||||
<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>
|
||||
@@ -91,7 +150,7 @@ export default function Series() {
|
||||
{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>
|
||||
<dd className={`text-right font-medium ${valor === "Não" || valor === "No" ? "text-muted" : "text-ink"}`}>{valor}</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
@@ -100,14 +159,14 @@ export default function Series() {
|
||||
{serie.aceleradores_ia && (
|
||||
<li className="chip chip-accent">
|
||||
<Sparkles className="h-3 w-3" aria-hidden="true" />
|
||||
Aceleradores de IA
|
||||
{isEs ? "Aceleradores de IA" : isEn ? "AI Accelerators" : "Aceleradores de IA"}
|
||||
</li>
|
||||
)}
|
||||
<li className="chip">
|
||||
<ShieldCheck className="h-3 w-3 text-accent" aria-hidden="true" />
|
||||
{nivelSeguranca(serie)}
|
||||
{nivelSeguranca(serie, isEn, isEs)}
|
||||
</li>
|
||||
{serie.matter === "Sim" && (
|
||||
{(serie.matter === "Sim" || serie.matter === "Yes" || serie.matter === "Sí") && (
|
||||
<li className="chip">
|
||||
<Home className="h-3 w-3 text-accent" aria-hidden="true" />
|
||||
Matter
|
||||
@@ -116,13 +175,13 @@ export default function Series() {
|
||||
{serie.status_documentacao && (
|
||||
<li className="chip">
|
||||
<AlertTriangle className="h-3 w-3 text-gold" aria-hidden="true" />
|
||||
Documentação preliminar
|
||||
{isEs ? "Documentación preliminar" : isEn ? "Preliminary documentation" : "Documentação preliminar"}
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
|
||||
<span className="mt-5 inline-flex items-center gap-1 text-sm font-medium text-accent">
|
||||
Abrir ficha
|
||||
{isEs ? "Abrir ficha" : 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>
|
||||
@@ -134,14 +193,20 @@ export default function Series() {
|
||||
<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>
|
||||
<h2 className="section-title">
|
||||
{isEs ? "¿Tiene dudas entre dos series?" : isEn ? "Unsure between two series?" : "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.
|
||||
{isEs
|
||||
? "El comparador coloca hasta cuatro modelos lado a lado: núcleos, radio, memoria, periféricos y seguridad."
|
||||
: 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="/comparacao" className="btn btn-primary shrink-0">
|
||||
<Link href={getLocalizedHref("/comparacao", currentLocale)} className="btn btn-primary shrink-0">
|
||||
<Scale className="h-4 w-4" aria-hidden="true" />
|
||||
Comparar séries
|
||||
{isEs ? "Comparar series" : isEn ? "Compare series" : "Comparar séries"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
+139
-49
@@ -8,36 +8,70 @@ import { ArrowUpRight, Code, Globe, GitCompare, Info, Languages } from "lucide-r
|
||||
|
||||
const REPOSITORIO = SITE.repositorio;
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
return paginaMeta({
|
||||
titulo: isEs ? "Acerca del proyecto" : isEn ? "About the Project" : "Sobre o projeto",
|
||||
descricao: isEs
|
||||
? "ESPDocs es una plataforma independiente que organiza la documentación técnica del ecosistema ESP32. Conozca el proyecto y cómo contribuir."
|
||||
: 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: isEs
|
||||
? ["ESPDocs", "documentación ESP32", "proyecto open source ESP32", "código abierto"]
|
||||
: isEn
|
||||
? ["ESPDocs", "ESP32 documentation", "open source ESP32 project"]
|
||||
: ["ESPDocs", "documentação ESP32 português", "projeto open source ESP32"],
|
||||
locale,
|
||||
});
|
||||
}
|
||||
|
||||
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 async function Sobre({ params }) {
|
||||
const { locale } = await params;
|
||||
const isPt = locale === "pt";
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
|
||||
export default function Sobre() {
|
||||
const features = [
|
||||
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 featuresEs = [
|
||||
{ icon: Languages, title: "En español", desc: "Datos técnicos organizados y presentados de forma clara en español neutro." },
|
||||
{ icon: GitCompare, title: "Comparaciones visuales", desc: "Tablas y diagramas para elegir la serie adecuada sin abrir diez hojas de datos." },
|
||||
{ icon: Globe, title: "Acceso centralizado", desc: "Enlaces directos a la documentación oficial, repositorios y ejemplos." },
|
||||
{ icon: Code, title: "Código abierto", desc: "Las contribuciones son bienvenidas en Gitea." },
|
||||
];
|
||||
|
||||
const features = isEs ? featuresEs : isEn ? featuresEn : featuresPt;
|
||||
|
||||
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()) }}
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd.paginaSobre(locale)) }}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: "Início", caminho: "/" },
|
||||
{ nome: "Sobre o Projeto", caminho: "/sobre" },
|
||||
{ nome: isEs ? "Inicio" : isPt ? "Início" : "Home", caminho: isEn ? "/en" : isEs ? "/es" : "/" },
|
||||
{ nome: isEs ? "Acerca del proyecto" : isPt ? "Sobre o Projeto" : "About the Project", caminho: isEn ? "/en/about" : isEs ? "/es/acerca" : "/sobre" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
@@ -47,15 +81,23 @@ export default function Sobre() {
|
||||
|
||||
<main id="conteudo">
|
||||
<PageHero
|
||||
trail={[{ label: "Sobre" }]}
|
||||
isEn={isEn}
|
||||
isEs={isEs}
|
||||
trail={[{ label: isEs ? "Acerca" : isPt ? "Sobre" : "About" }]}
|
||||
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."
|
||||
label={isEs ? "Proyecto independiente" : isPt ? "Projeto independente" : "Independent project"}
|
||||
title={isEs ? "Acerca de ESPDocs" : isPt ? "Sobre o ESPDocs" : "About ESPDocs"}
|
||||
lede={
|
||||
isEs
|
||||
? "Una plataforma no oficial, en español, que organiza la información técnica del ESP32 y le conecta con la documentación oficial de Espressif. Creada para la comunidad de hardware abierto."
|
||||
: 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" />
|
||||
Ver o repositório
|
||||
{isEs ? "Ver el repositorio" : isPt ? "Ver o repositório" : "View repository"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</PageHero>
|
||||
@@ -63,20 +105,24 @@ export default function Sobre() {
|
||||
<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>
|
||||
<h2 id="missao" className="section-title">{isEs ? "Misión" : isPt ? "Missão" : "Mission"}</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.
|
||||
{isEs
|
||||
? "Facilitar el acceso y la comprensión del ecosistema ESP32 con una interfaz en español que organiza especificaciones, compara series, presenta frameworks y centraliza los enlaces a la documentación oficial. El objetivo es ahorrar tiempo en el desarrollo de firmware e IoT."
|
||||
: 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">Por que o ESPDocs existe</h2>
|
||||
<h2 id="porque" className="section-title">{isEs ? "¿Por qué existe ESPDocs?" : isPt ? "Por que o ESPDocs existe" : "Why ESPDocs exists"}</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.
|
||||
{isEs
|
||||
? "La información sobre el ESP32 suele estar dispersa entre hojas de datos densas, manuales de referencia técnica (TRM) y repositorios secundarios. ESPDocs condensa y estructura estos datos para una evaluación rápida antes de profundizar en la ingeniería oficial."
|
||||
: 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 }) => (
|
||||
@@ -94,17 +140,33 @@ export default function Sobre() {
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="contribuir">
|
||||
<h2 id="contribuir" className="section-title">Como contribuir</h2>
|
||||
<h2 id="contribuir" className="section-title">{isEs ? "Cómo contribuir" : isPt ? "Como contribuir" : "How to contribute"}</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.
|
||||
{isEs
|
||||
? "Las correcciones de traducción, ajustes en tablas y nuevos ejemplos de código son muy bienvenidos. El proyecto crece junto con la comunidad."
|
||||
: 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">
|
||||
{[
|
||||
"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) => (
|
||||
{(isEs
|
||||
? [
|
||||
"Haga un fork del repositorio en Gitea.",
|
||||
"Implemente las mejoras y verifique las referencias técnicas oficiales.",
|
||||
"Abra una solicitud de extracción (Pull Request) describiendo los cambios realizados.",
|
||||
]
|
||||
: 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}
|
||||
@@ -116,15 +178,18 @@ export default function Sobre() {
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="acessibilidade">
|
||||
<h2 id="acessibilidade" className="section-title">Acessibilidade</h2>
|
||||
<h2 id="acessibilidade" className="section-title">{isEs ? "Accesibilidad" : isPt ? "Acessibilidade" : "Accessibility"}</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.
|
||||
{isEs
|
||||
? "ESPDocs prioriza la legibilidad, el alto contraste (nivel AAA de WCAG) y la navegación completa por teclado. Si encuentra alguna barrera de lectura o navegación, abra un issue en el repositorio."
|
||||
: 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="Autor e aviso legal">
|
||||
<aside className="space-y-5 lg:sticky lg:top-28 lg:self-start" aria-label={isEs ? "Autor y aviso legal" : 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">
|
||||
@@ -132,30 +197,55 @@ export default function Sobre() {
|
||||
</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>
|
||||
<p className="text-sm text-muted">{isEs ? "Creador de Ciência Embarcada" : 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">
|
||||
<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>
|
||||
{isEs ? (
|
||||
<>
|
||||
<p>
|
||||
Técnico en Desarrollo de Sistemas, estudiante de Ciencias de la Computación en la UFRPE e investigador en Blockchain y Criptografía.
|
||||
</p>
|
||||
<p>
|
||||
Director de Software en Semine AgriTech y ponente en eventos como REC'n'Play, compartiendo contenido sobre hardware, IoT y ciberseguridad.
|
||||
</p>
|
||||
</>
|
||||
) : 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">
|
||||
Visitar o Ciência Embarcada
|
||||
{isEs ? "Visitar Ciência Embarcada" : 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">Aviso legal</p>
|
||||
<p className="font-semibold text-ink">{isEs ? "Aviso legal" : isPt ? "Aviso legal" : "Legal notice"}</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.
|
||||
{isEs
|
||||
? "ESPDocs es un agregador y organizador. Los manuales y repositorios referenciados pertenecen a Espressif Systems. En proyectos críticos o comerciales, consulte siempre la documentación oficial."
|
||||
: 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>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { construirIndiceBusca } from "@/lib/searchIndex";
|
||||
|
||||
export const dynamic = "force-static";
|
||||
|
||||
export function generateStaticParams() {
|
||||
return [{ locale: "pt" }, { locale: "en" }, { locale: "es" }];
|
||||
}
|
||||
|
||||
export async function GET(request, { params }) {
|
||||
const { locale } = await params;
|
||||
const loc = locale === "en" ? "en" : locale === "es" ? "es" : "pt";
|
||||
return Response.json(construirIndiceBusca(loc), {
|
||||
headers: {
|
||||
"Cache-Control": "no-cache, no-store, must-revalidate",
|
||||
},
|
||||
});
|
||||
}
|
||||
+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,8 +1,51 @@
|
||||
"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",
|
||||
};
|
||||
|
||||
const HEADER_MAP_ES = {
|
||||
"Nome": "Nombre",
|
||||
"Descrição": "Descripción",
|
||||
"Série": "Serie",
|
||||
"Loja Oficial": "Tienda oficial",
|
||||
"Fabricante": "Fabricante",
|
||||
"Processador": "Procesador",
|
||||
"Memória Flash": "Memoria flash",
|
||||
"PSRAM": "PSRAM",
|
||||
"Conector USB": "Conector USB",
|
||||
"Interface USB": "Interfaz USB",
|
||||
"Antena": "Antena",
|
||||
"Bateria": "Batería",
|
||||
"Display": "Pantalla",
|
||||
"Sensores": "Sensores",
|
||||
"Botões": "Botones",
|
||||
"LEDs": "LEDs",
|
||||
};
|
||||
|
||||
export default function BoardCard({ board }) {
|
||||
const pathname = usePathname() || "";
|
||||
const isEn = pathname === "/en" || pathname.startsWith("/en/");
|
||||
const isEs = pathname === "/es" || pathname.startsWith("/es/");
|
||||
|
||||
const mainFields = ["Nome", "Link", "Imagem", "Loja Oficial"];
|
||||
|
||||
const technicalFields = Object.keys(board).filter((key) => !mainFields.includes(key) && board[key]);
|
||||
@@ -24,20 +67,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" : isEs ? "Tienda oficial" : "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" : isEs ? "Placa genérica" : "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" : isEs ? "Recursos integrados" : "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) : isEs ? (HEADER_MAP_ES[campo] || campo) : campo;
|
||||
return (
|
||||
<li key={campo} className={`chip ${opcional ? "text-gold" : "text-ink-soft"}`}>
|
||||
{opcional ? (
|
||||
@@ -45,8 +89,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 +100,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" : isEs ? "Ver en 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)" : isEs ? " (abre en una pestaña nueva)" : " (abre em nova aba)"}</span>
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
|
||||
+66
-16
@@ -2,8 +2,14 @@
|
||||
|
||||
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 isEs = pathname === "/es" || pathname.startsWith("/es/");
|
||||
const loc = isEn ? "en" : isEs ? "es" : "pt";
|
||||
|
||||
const examplesUrl = framework?.exemplos;
|
||||
|
||||
const [sample, setSample] = useState("");
|
||||
@@ -20,18 +26,38 @@ 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`
|
||||
: isEs
|
||||
? `// Ejemplos completos: ${examplesUrl || "ver repositorio"}\n`
|
||||
: `// Exemplos completos: ${examplesUrl || "ver repositório"}\n`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const url = exemploPath.startsWith("/") ? exemploPath : `/${exemploPath}`;
|
||||
// Se locale for diferente de pt, busca primeiro em /exemplos/<loc>/
|
||||
let url = exemploPath.startsWith("/") ? exemploPath : `/${exemploPath}`;
|
||||
if (loc !== "pt" && url.startsWith("/exemplos/") && !url.startsWith(`/exemplos/${loc}/`)) {
|
||||
url = url.replace("/exemplos/", `/exemplos/${loc}/`);
|
||||
}
|
||||
|
||||
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 +65,26 @@ 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"
|
||||
: isEs
|
||||
? "// El archivo de ejemplo está vacío. Consulte el repositorio oficial.\n"
|
||||
: "// O arquivo de exemplo está vazio. Consulte o repositório oficial.\n"
|
||||
);
|
||||
setError(isEn ? "empty file" : isEs ? "archivo vacío" : "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"
|
||||
: isEs
|
||||
? "// No fue posible cargar el ejemplo.\n// Consulte el repositorio oficial para ver los ejemplos completos.\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" : isEs ? "fallo al cargar" : "falha ao carregar"));
|
||||
})
|
||||
.finally(() => {
|
||||
if (!cancelled) setLoading(false);
|
||||
@@ -55,7 +93,7 @@ export default function CodeExample({ framework }) {
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [framework?.exemplo, framework?.exemplos]);
|
||||
}, [framework?.exemplo, framework?.exemplos, isEn, isEs, loc]);
|
||||
|
||||
const lines = (sample || "").replace(/\n$/, "").split("\n");
|
||||
|
||||
@@ -71,20 +109,28 @@ 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" : isEs ? "Ejemplo de código" : "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.`
|
||||
: isEs
|
||||
? `Fragmento de inicio en ${framework?.linguagem}. Ajuste los pines y la configuración para su placa.`
|
||||
: `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" : isEs ? "Copiado" : "Copiado") : (isEn ? "Copy" : isEs ? "Copiar" : "Copiar")}</span>
|
||||
</button>
|
||||
{examplesUrl && (
|
||||
<a href={examplesUrl} target="_blank" rel="noopener noreferrer" className="btn btn-ghost btn-sm">
|
||||
Mais exemplos
|
||||
{isEn ? "More examples" : isEs ? "Más ejemplos" : "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)" : isEs ? " (abre en una pestaña nueva)" : " (abre em nova aba)"}</span>
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
@@ -93,9 +139,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…" : isEs ? "Cargando ejemplo…" : "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}` : isEs ? `Código de ejemplo en ${framework?.linguagem}` : `Código de exemplo em ${framework?.linguagem}`}>
|
||||
<code>
|
||||
{lines.map((line, idx) => (
|
||||
<span key={idx} className="flex">
|
||||
@@ -109,7 +155,11 @@ 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.`
|
||||
: isEs
|
||||
? `No se pudo cargar el ejemplo local (${error}). Utilice “Más ejemplos” para ver el código oficial.`
|
||||
: `Não foi possível carregar o exemplo local (${error}). Use “Mais exemplos” para ver o código oficial.`}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -33,6 +33,52 @@ 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 FILTER_CATEGORIES_ES = [
|
||||
{ id: "All", name: "Todos", color: "#8b5cf6" },
|
||||
{ id: "GND", name: "Tierra (GND)", color: "#64748b" },
|
||||
{ id: "Power", name: "Alimentación", color: "#ef4444" },
|
||||
{ id: "GPIO", name: "GPIO", color: "#22c55e" },
|
||||
{ id: "Low Power", name: "GPIO LP", 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: "Reloj", color: "#eab308" },
|
||||
{ id: "JTAG", name: "JTAG", color: "#6366f1" },
|
||||
{ id: "Strapping", name: "Arranque (Boot)", color: "#dc2626" },
|
||||
{ id: "DSI", name: "Pantalla (DSI)", color: "#f97316" },
|
||||
{ id: "CSI", name: "Cámara (CSI)", color: "#14b8a6" },
|
||||
{ id: "Ethernet", name: "Ethernet", color: "#0284c7" },
|
||||
{ id: "SD", name: "Tarjeta SD", color: "#10b981" },
|
||||
{ id: "I2C", name: "I2C", color: "#f59e0b" },
|
||||
{ id: "Antena", name: "Antena", color: "#06b6d4" },
|
||||
];
|
||||
|
||||
const type_colors = {
|
||||
power: "#ef4444", // high-voltage red
|
||||
ground: "#64748b", // slate gray
|
||||
@@ -58,6 +104,8 @@ export default function ConnectionsDiagram(props) {
|
||||
function ConnectionsDiagramInner({ connections, serie }) {
|
||||
const params = useSearchParams();
|
||||
const pathname = usePathname();
|
||||
const isEn = pathname?.startsWith("/en");
|
||||
const isEs = pathname?.startsWith("/es");
|
||||
const router = useRouter();
|
||||
const pinosFiltro = useMemo(() => new Set((params.get("pinos") ?? "").split(",").filter(Boolean)), [params]);
|
||||
const motivoFiltro = params.get("motivo") ?? "";
|
||||
@@ -69,6 +117,8 @@ function ConnectionsDiagramInner({ connections, serie }) {
|
||||
const dialogRef = useRef(null);
|
||||
const gatilhoRef = useRef(null);
|
||||
|
||||
const filterCategories = isEn ? FILTER_CATEGORIES_EN : isEs ? FILTER_CATEGORIES_ES : FILTER_CATEGORIES;
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
@@ -84,11 +134,22 @@ 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" : isEs ? "Arranque (Boot)" : "Inicialização";
|
||||
if (isEn) {
|
||||
const found = FILTER_CATEGORIES_EN.find((f) => f.id === cat);
|
||||
if (found) return found.name;
|
||||
}
|
||||
if (isEs) {
|
||||
const found = FILTER_CATEGORIES_ES.find((f) => f.id === cat);
|
||||
if (found) return found.name;
|
||||
}
|
||||
return cat;
|
||||
};
|
||||
|
||||
const visibleConnections = useMemo(() => connections.filter(isConnectionVisible), [connections, activeFilter, searchQuery, pinosFiltro]);
|
||||
|
||||
@@ -142,8 +203,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" : isEs ? "Diagrama de conexiones no disponible" : "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." : isEs ? "Este modelo todavía no dispone de un mapa detallado de conexiones y buses." : "Este modelo ainda não tem um mapa detalhado de conexões e barramentos."}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -153,59 +218,75 @@ 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" : isEs ? "Diagrama de conexiones interactivo" : "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.`
|
||||
) : isEs ? (
|
||||
`Todas las conexiones y la multiplexación del ${serie.nome_completo}. Busque por nombre o número, filtre por función y abra un pin para ver los detalles.`
|
||||
) : (
|
||||
`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:" : isEs ? "Filtrado por la búsqueda:" : "Filtrado pela busca:"}</strong> {motivoFiltro || (isEn ? "selected pins" : isEs ? "pines seleccionados" : "pinos selecionados")} ({pinosFiltro.size}{" "}
|
||||
{pinosFiltro.size === 1 ? (isEn ? "pin" : isEs ? "pin" : "pino") : (isEn ? "pins" : isEs ? "pines" : "pinos")})
|
||||
</p>
|
||||
<button type="button" onClick={mostrarTodos} className="btn btn-ghost btn-sm">
|
||||
Mostrar todos os pinos
|
||||
{isEn ? "Show all pins" : isEs ? "Mostrar todos los pines" : "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" : isEs ? "Buscar conexión por nombre o número" : "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)" : isEs ? "Buscar pin (ej.: 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" : isEs ? "Modo de visualización" : "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" : isEs ? "Cuadrícula" : "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" : isEs ? "Lista" : "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" : isEs ? "Función del pin" : "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`
|
||||
) : isEs ? (
|
||||
`${visibleConnections.length} de ${connections.length} pines`
|
||||
) : (
|
||||
`${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" : isEs ? "Filtrar por función" : "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,10 +304,10 @@ 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" : isEs ? "No se encontraron conexiones" : "Nenhuma conexão encontrada"}</p>
|
||||
<p className="mt-1 text-sm text-muted">{isEn ? "Adjust your search or return to all functions." : isEs ? "Ajuste la búsqueda o vuelva a todas las funciones." : "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
|
||||
{isEn ? "Clear search and filters" : isEs ? "Limpiar búsqueda y filtros" : "Limpar busca e filtros"}
|
||||
</button>
|
||||
</div>
|
||||
) : viewMode === "grid" ? (
|
||||
@@ -239,7 +320,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" : ""}` : isEs ? `Pin ${connection.nome}, número ${connection.numero}${connection.avisos ? ", con restricciones de uso" : ""}` : `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 +348,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}` : isEs ? `Conexiones del ${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" : isEs ? "Pin" : "Pino"}</th>
|
||||
<th scope="col" className="px-4 py-3 font-medium">{isEn ? "Name" : isEs ? "Nombre" : "Nome"}</th>
|
||||
<th scope="col" className="px-4 py-3 font-medium">{isEn ? "Functions" : isEs ? "Funciones" : "Funções"}</th>
|
||||
<th scope="col" className="px-4 py-3 font-medium">{isEn ? "Usage" : isEs ? "Uso" : "Uso"}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-line">
|
||||
@@ -286,7 +369,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}` : isEs ? `Abrir detalles del pin ${connection.nome}, número ${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 +384,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" : isEs ? "Restringido" : "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" : isEs ? "Libre" : "Livre"}
|
||||
</span>
|
||||
)}
|
||||
</td>
|
||||
@@ -322,10 +405,24 @@ 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" : isEs ? "Notas sobre el patillaje" : "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>
|
||||
</>
|
||||
) : isEs ? (
|
||||
<>
|
||||
<li>Los pines con icono de advertencia tienen un papel especial en el arranque o limitaciones analógicas. Abra el pin para ver los detalles.</li>
|
||||
<li>Aísle las pistas táctiles capacitivas del ruido de RF acoplado.</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 +450,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}` : isEs ? `Pin físico ${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" : isEs ? "Cerrar detalles del pin" : "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 +463,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" : isEs ? "Categorías" : "Categorias"}</h4>
|
||||
<ul className="mt-3 flex flex-wrap gap-2">
|
||||
{selectedConnection.categorias.map((cat) => (
|
||||
<li key={cat} className="chip">
|
||||
@@ -380,7 +479,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" : isEs ? "Dominio de alimentación" : "Domínio de alimentação"}
|
||||
</h4>
|
||||
<ul className="tile mt-3 space-y-2">
|
||||
{selectedConnection.alimentacao.map((source) => (
|
||||
@@ -391,7 +490,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" : isEs ? "Funciones disponibles" : "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 +505,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" : isEs ? "Notas de ingeniería" : "Avisos de engenharia"}
|
||||
</h4>
|
||||
<ul className="mt-2 list-disc space-y-1.5 pl-5">
|
||||
{selectedConnection.avisos.map((aviso) => (
|
||||
@@ -418,7 +517,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" : isEs ? "Cerrar" : "Fechar"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
|
||||
+120
-37
@@ -6,16 +6,16 @@ import Logo from "@/components/Logo";
|
||||
import GiteaMark from "@/components/GiteaMark";
|
||||
import { ArrowUpRight } from "lucide-react";
|
||||
import { SITE } from "@/lib/seo";
|
||||
import { LOCALES, getLocalizedHref } from "@/components/LanguageSelector";
|
||||
import { LOCALES, getLocalizedHref } from "@/i18n/links";
|
||||
|
||||
const BASE_COLUMNS = [
|
||||
const COLUMNS_PT = [
|
||||
{
|
||||
title: "Explorar",
|
||||
links: [
|
||||
{ href: "/series", label: "Séries ESP32" },
|
||||
{ href: "/comparacao", label: "Comparador" },
|
||||
{ href: "/catalogo", label: "Catálogo de placas" },
|
||||
{ href: "/livro", label: "O livro", livroOnly: true },
|
||||
{ href: "/livro", label: "O livro" },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -38,6 +38,64 @@ const BASE_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 },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const COLUMNS_ES = [
|
||||
{
|
||||
title: "Explorar",
|
||||
links: [
|
||||
{ href: "/series", label: "Series ESP32" },
|
||||
{ href: "/comparacao", label: "Comparador" },
|
||||
{ href: "/catalogo", label: "Catálogo de placas" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Herramientas",
|
||||
links: [
|
||||
{ href: "/seletor", label: "Selector inteligente" },
|
||||
{ href: "/diagnostico", label: "Diagnóstico" },
|
||||
{ href: "/componentes", label: "Component Registry" },
|
||||
{ href: "/frameworks", label: "Frameworks y SDKs" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Proyecto",
|
||||
links: [
|
||||
{ href: "/sobre", label: "Acerca de ESPDocs" },
|
||||
{ href: "/glossario", label: "Glosario" },
|
||||
{ href: SITE.repositorio, label: "Repositorio", external: true },
|
||||
{ href: `${SITE.repositorio}/issues`, label: "Reportar un problema", external: true },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default function Footer() {
|
||||
const pathname = usePathname() || "";
|
||||
const year = new Date().getFullYear();
|
||||
@@ -45,26 +103,46 @@ export default function Footer() {
|
||||
const currentLocale =
|
||||
LOCALES.find((l) => pathname === `/${l.code}` || pathname.startsWith(`/${l.code}/`))?.code || "pt";
|
||||
const isPt = currentLocale === "pt";
|
||||
const isEn = currentLocale === "en";
|
||||
const isEs = currentLocale === "es";
|
||||
|
||||
const getLinkHref = (href) => getLocalizedHref(`/${currentLocale}${href}`, currentLocale);
|
||||
|
||||
const columns = BASE_COLUMNS.map((col) => ({
|
||||
...col,
|
||||
links: col.links.filter((l) => !l.livroOnly || isPt),
|
||||
}));
|
||||
const columns = isPt
|
||||
? COLUMNS_PT.map((column) => ({
|
||||
...column,
|
||||
links: column.links.filter((link) => link.href !== "/livro" || isPt),
|
||||
}))
|
||||
: isEs
|
||||
? COLUMNS_ES
|
||||
: 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" : isEs ? "Pie de página de 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={getLinkHref("/")} 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" : isEs ? "ESPDocs, página de inicio" : "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.
|
||||
</>
|
||||
) : isEs ? (
|
||||
<>
|
||||
Documentación independiente del ecosistema ESP32.
|
||||
Datos públicos, curaduría editorial y enlaces a las fuentes oficiales.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Independent documentation of the ESP32 ecosystem.
|
||||
Open data, editorial curation, and links to official sources.
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
|
||||
{isPt && (
|
||||
@@ -133,46 +211,51 @@ 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" : isEs ? "Autor" : "Author"}</h2>
|
||||
<p className="mt-4 text-sm leading-relaxed text-muted">
|
||||
Lucas Rayan Guerra
|
||||
<br />
|
||||
<span className="text-xs text-faint">Ciência Embarcada</span>
|
||||
</p>
|
||||
<div className="mt-2 flex flex-wrap gap-x-4 gap-y-1 text-sm">
|
||||
<a href={SITE.autorUrl} target="_blank" rel="noopener noreferrer" className="inline-flex min-h-11 items-center text-muted transition-colors hover:text-accent">
|
||||
Site pessoal
|
||||
<div className="mt-4 flex items-center gap-2">
|
||||
<a
|
||||
href={SITE.repositorio}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label={isPt ? "Gitea do projeto (abre em nova aba)" : isEs ? "Gitea del proyecto (abre en una pestaña nueva)" : "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" />
|
||||
</a>
|
||||
<a href={SITE.autorLinkedin} target="_blank" rel="noopener noreferrer" className="inline-flex min-h-11 items-center text-muted transition-colors hover:text-accent">
|
||||
LinkedIn
|
||||
<a
|
||||
href={SITE.autorLinkedin}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label={isPt ? "LinkedIn do autor (abre em nova aba)" : isEs ? "LinkedIn del autor (abre en una pestaña nueva)" : "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">
|
||||
<path d="M4.98 3.5a2.5 2.5 0 1 1 0 5.001 2.5 2.5 0 0 1 0-5zM3 8.98h4v12H3v-12zm6.5 0h3.8v1.6h.1c.5-.9 1.8-1.9 3.6-1.9 3.8 0 4.5 2.5 4.5 5.8v6.5h-4v-5.8c0-1.4-.1-3.2-2-3.2-2 0-2.3 1.6-2.3 3.1v5.9h-4v-12z" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-12 flex flex-col items-center justify-between gap-4 border-t border-line pt-8 text-xs text-muted sm:flex-row">
|
||||
<p>© {year} ESPDocs · Conteúdo sob licença MIT. Feito para a comunidade de sistemas embarcados.</p>
|
||||
<div className="flex items-center gap-6">
|
||||
<a
|
||||
href={SITE.repositorio}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex min-h-11 items-center gap-1.5 transition-colors hover:text-accent"
|
||||
>
|
||||
<GiteaMark className="h-4 w-4" aria-hidden="true" />
|
||||
<span>Gitea</span>
|
||||
</a>
|
||||
<span>·</span>
|
||||
<a
|
||||
href={SITE.blog}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex min-h-11 items-center transition-colors hover:text-accent"
|
||||
>
|
||||
<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} {isPt ? "ESPDocs. Projeto independente, sem afiliação com a Espressif Systems." : isEs ? "ESPDocs. Proyecto independiente, sin afiliación con 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
|
||||
<ArrowUpRight className="h-3 w-3" aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
<a href={SITE.autorUrl} target="_blank" rel="noopener noreferrer" className="inline-flex min-h-11 items-center gap-1 transition-colors hover:text-accent">
|
||||
lucasrguerra.dev.br
|
||||
<ArrowUpRight className="h-3 w-3" aria-hidden="true" />
|
||||
</a>
|
||||
<span>{isPt ? "Fontes oficiais: Espressif Systems." : isEs ? "Fuentes oficiales: Espressif Systems." : "Official sources: Espressif Systems."}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
+107
-19
@@ -5,7 +5,8 @@ import { createPortal } from "react-dom";
|
||||
import Link from "next/link";
|
||||
import Logo from "@/components/Logo";
|
||||
import SearchDialog from "@/components/SearchDialog";
|
||||
import LanguageSelector, { LOCALES, getLocalizedHref } from "@/components/LanguageSelector";
|
||||
import LanguageSelector from "@/components/LanguageSelector";
|
||||
import { LOCALES, getLocalizedHref } from "@/i18n/links";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useTheme } from "next-themes";
|
||||
import {
|
||||
@@ -27,7 +28,7 @@ import {
|
||||
AlertTriangle,
|
||||
} from "lucide-react";
|
||||
|
||||
const MENUS = [
|
||||
const MENUS_PT = [
|
||||
{
|
||||
id: "hardware",
|
||||
label: "Hardware",
|
||||
@@ -57,7 +58,67 @@ 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 MENUS_ES = [
|
||||
{
|
||||
id: "hardware",
|
||||
label: "Hardware",
|
||||
items: [
|
||||
{ href: "/series", label: "Series ESP32", desc: "12 chips, patillaje y especificaciones", icon: Cpu },
|
||||
{ href: "/comparacao", label: "Comparador", desc: "Hasta cuatro series frente a frente", icon: Scale },
|
||||
{ href: "/catalogo", label: "Catálogo de placas", desc: "DevKits, pines y dónde comprar", icon: Box },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "tools",
|
||||
label: "Herramientas",
|
||||
items: [
|
||||
{ href: "/seletor", label: "Selector inteligente", desc: "El chip adecuado para su proyecto", icon: SlidersHorizontal },
|
||||
{ href: "/diagnostico", label: "Diagnóstico", desc: "Brownout, bootloop, WDT y más", icon: AlertTriangle },
|
||||
{ href: "/componentes", label: "Component Registry", desc: "Drivers y manifiestos idf_component.yml", icon: Search },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "library",
|
||||
label: "Biblioteca",
|
||||
items: [
|
||||
{ href: "/frameworks", label: "Frameworks y SDKs", desc: "ESP-IDF, Arduino, Rust y Matter", icon: BookOpen },
|
||||
{ href: "/glossario", label: "Glosario técnico", desc: "Términos que aparecen en las hojas de datos", icon: BookA },
|
||||
{ href: "/sobre", label: "Acerca del proyecto", desc: "Autoría, método y código abierto", icon: Sparkles },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const MOBILE_LINKS_PT = [
|
||||
{ href: "/series", label: "Séries ESP32" },
|
||||
{ href: "/comparacao", label: "Comparador" },
|
||||
{ href: "/seletor", label: "Seletor inteligente" },
|
||||
@@ -70,6 +131,30 @@ const MOBILE_LINKS = [
|
||||
{ href: "/sobre", label: "Sobre" },
|
||||
];
|
||||
|
||||
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" },
|
||||
];
|
||||
|
||||
const MOBILE_LINKS_ES = [
|
||||
{ href: "/series", label: "Series ESP32" },
|
||||
{ href: "/comparacao", label: "Comparador" },
|
||||
{ href: "/seletor", label: "Selector inteligente" },
|
||||
{ href: "/diagnostico", label: "Diagnóstico" },
|
||||
{ href: "/frameworks", label: "Frameworks y SDKs" },
|
||||
{ href: "/componentes", label: "Component Registry" },
|
||||
{ href: "/glossario", label: "Glosario" },
|
||||
{ href: "/catalogo", label: "Catálogo de placas" },
|
||||
{ href: "/sobre", label: "Acerca de" },
|
||||
];
|
||||
|
||||
function isActivePath(pathname, href, currentLocale) {
|
||||
const localized = getLocalizedHref(`/${currentLocale}${href}`, currentLocale);
|
||||
if (href === "/" || localized === `/${currentLocale}/` || localized === `/${currentLocale}`) {
|
||||
@@ -90,6 +175,8 @@ export default function Header() {
|
||||
const currentLocale =
|
||||
LOCALES.find((l) => pathname === `/${l.code}` || pathname.startsWith(`/${l.code}/`))?.code || "pt";
|
||||
const isPt = currentLocale === "pt";
|
||||
const isEn = currentLocale === "en";
|
||||
const isEs = currentLocale === "es";
|
||||
|
||||
const getLinkHref = (href) => getLocalizedHref(`/${currentLocale}${href}`, currentLocale);
|
||||
|
||||
@@ -129,18 +216,19 @@ export default function Header() {
|
||||
};
|
||||
}, [drawerOpen]);
|
||||
|
||||
const visibleMobileLinks = isPt ? MOBILE_LINKS : MOBILE_LINKS.filter((l) => l.href !== "/livro");
|
||||
const visibleMobileLinks = isPt ? MOBILE_LINKS_PT : isEs ? MOBILE_LINKS_ES : MOBILE_LINKS_EN;
|
||||
const MENUS = isPt ? MENUS_PT : isEs ? MENUS_ES : 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={getLinkHref("/")} 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" : isEs ? "ESPDocs, página de inicio" : "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" : isEs ? "Navegación principal" : "Main navigation"}>
|
||||
{MENUS.map((menu) => {
|
||||
const active = menu.items.some((item) => isActivePath(pathname, item.href, currentLocale));
|
||||
const expanded = openMenu === menu.id;
|
||||
@@ -193,23 +281,23 @@ export default function Header() {
|
||||
</Link>
|
||||
)}
|
||||
<Link href={getLinkHref("/sobre")} className={`nav-link ${isActivePath(pathname, "/sobre", currentLocale) ? "is-active" : ""}`} aria-current={isActivePath(pathname, "/sobre", currentLocale) ? "page" : undefined}>
|
||||
Sobre
|
||||
{isPt ? "Sobre" : isEs ? "Acerca de" : "About"}
|
||||
</Link>
|
||||
</nav>
|
||||
|
||||
<div className="flex items-center gap-1.5">
|
||||
<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" : isEs ? "Seleccionar chip" : "Select chip"}
|
||||
</Link>
|
||||
<SearchDialog />
|
||||
<LanguageSelector />
|
||||
<ThemeToggle />
|
||||
<ThemeToggle isPt={isPt} isEs={isEs} />
|
||||
<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" : isEs ? "Abrir menú de navegación" : "Open navigation menu"}
|
||||
aria-expanded={drawerOpen}
|
||||
onClick={() => setDrawerOpen(true)}
|
||||
>
|
||||
@@ -232,7 +320,7 @@ export default function Header() {
|
||||
<div
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label="Menu de navegação"
|
||||
aria-label={isPt ? "Menu de navegação" : isEs ? "Menú de navegación" : "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 ${
|
||||
@@ -241,15 +329,15 @@ 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" : isEs ? "Navegación" : "Navigation"}</p>
|
||||
<p className="mt-1 font-display text-2xl font-semibold tracking-[-0.04em] text-ink">{isPt ? "Para onde ir" : isEs ? "A dónde 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" : isEs ? "Cerrar menú" : "Close menu"}
|
||||
>
|
||||
<X className="h-5 w-5" aria-hidden="true" />
|
||||
</button>
|
||||
@@ -281,7 +369,7 @@ export default function Header() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<nav className="flex-1 overflow-y-auto px-3 py-2" aria-label="Navegação móvel">
|
||||
<nav className="flex-1 overflow-y-auto px-3 py-2" aria-label={isPt ? "Navegação móvel" : isEs ? "Navegación móvil" : "Mobile navigation"}>
|
||||
{visibleMobileLinks.map((link) => (
|
||||
<Link
|
||||
key={link.href}
|
||||
@@ -299,7 +387,7 @@ export default function Header() {
|
||||
<div className="p-4 pt-2">
|
||||
<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" : isEs ? "Seleccionar mi chip" : "Select my chip"}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
@@ -310,7 +398,7 @@ export default function Header() {
|
||||
);
|
||||
}
|
||||
|
||||
function ThemeToggle() {
|
||||
function ThemeToggle({ isPt = true, isEs = false }) {
|
||||
const { resolvedTheme, setTheme } = useTheme();
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
@@ -327,8 +415,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" : isEs ? "Activar tema claro" : "Switch to light theme") : (isPt ? "Ativar tema escuro" : isEs ? "Activar tema oscuro" : "Switch to dark theme")}
|
||||
title={dark ? (isPt ? "Tema claro" : isEs ? "Tema claro" : "Light theme") : (isPt ? "Tema escuro" : isEs ? "Tema oscuro" : "Dark theme")}
|
||||
>
|
||||
{dark ? <Sun className="h-4 w-4" aria-hidden="true" /> : <Moon className="h-4 w-4" aria-hidden="true" />}
|
||||
</button>
|
||||
|
||||
@@ -3,133 +3,15 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { ChevronDown, Globe } from "lucide-react";
|
||||
import { LOCALES, getLocalizedHref } from "@/i18n/links";
|
||||
|
||||
export const LOCALES = [
|
||||
{ code: "pt", label: "Português", short: "PT", lang: "pt-BR" },
|
||||
{ code: "en", label: "English", short: "EN", lang: "en" },
|
||||
{ code: "es", label: "Español", short: "ES", lang: "es-419" },
|
||||
{ code: "fr", label: "Français", short: "FR", lang: "fr" },
|
||||
{ code: "de", label: "Deutsch", short: "DE", lang: "de" },
|
||||
{ code: "zh-CN", label: "简体中文", short: "中", lang: "zh-CN" },
|
||||
];
|
||||
|
||||
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 === "/" || pathname === `/${targetLocale}` || pathname === `/${targetLocale}/`) {
|
||||
return `/${targetLocale}/`;
|
||||
}
|
||||
|
||||
for (const route of CANONICAL_ROUTES) {
|
||||
const m = pathname.match(route.match);
|
||||
if (m) {
|
||||
const slug = route.getSlug(targetLocale, m[1]);
|
||||
return slug ? `/${targetLocale}${slug}` : `/${targetLocale}/`;
|
||||
}
|
||||
}
|
||||
return `/${targetLocale}/`;
|
||||
}
|
||||
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("");
|
||||
@@ -181,8 +63,8 @@ export default function LanguageSelector() {
|
||||
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={`Idioma atual: ${currentLocale.label}. Clique para trocar de idioma.`}
|
||||
title={`Idioma: ${currentLocale.label}`}
|
||||
aria-label={currentLocaleCode === "en" ? `Current language: ${currentLocale.label}. Click to switch language.` : currentLocaleCode === "es" ? `Idioma actual: ${currentLocale.label}. Haga clic para cambiar de idioma.` : `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>
|
||||
@@ -195,7 +77,7 @@ export default function LanguageSelector() {
|
||||
{open && (
|
||||
<div
|
||||
role="listbox"
|
||||
aria-label="Idiomas disponíveis"
|
||||
aria-label={currentLocaleCode === "en" ? "Available languages" : currentLocaleCode === "es" ? "Idiomas disponibles" : "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) => {
|
||||
|
||||
+28
-4
@@ -5,14 +5,38 @@ 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,
|
||||
isEs: isEsProp,
|
||||
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")));
|
||||
const isEs =
|
||||
isEsProp !== undefined
|
||||
? isEsProp
|
||||
: localeProp
|
||||
? localeProp === "es"
|
||||
: trail.some((t) => t.isEs || (t.href && t.href.startsWith("/es")));
|
||||
|
||||
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" : isEs ? "Navegación por migas de pan" : "Trilha de navegação"} className="flex flex-wrap items-center gap-2 text-sm text-muted">
|
||||
<Link href={isEn ? "/en" : isEs ? "/es" : "/"} className="inline-flex min-h-11 min-w-11 items-center justify-center transition-colors hover:text-accent">
|
||||
{isEn ? "Home" : isEs ? "Inicio" : "Início"}
|
||||
</Link>
|
||||
{trail.map((item, i) => (
|
||||
<span key={item.label} className="flex min-h-11 items-center gap-2">
|
||||
|
||||
+163
-20
@@ -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,129 @@ 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),
|
||||
},
|
||||
];
|
||||
|
||||
const GRUPOS_ES = [
|
||||
{
|
||||
id: "entrada",
|
||||
titulo: "Solo entrada",
|
||||
icone: ArrowDownToLine,
|
||||
cor: "text-accent",
|
||||
explicacao:
|
||||
"Aceptan únicamente lectura. No pueden configurarse como salida y no poseen resistencias de pull-up o pull-down internas. Si necesita una, agréguela en el circuito externo.",
|
||||
combina: (avisos) => /solo de entrada|input[- ]only/i.test(avisos),
|
||||
},
|
||||
{
|
||||
id: "flash",
|
||||
titulo: "Conectados a la memoria flash/PSRAM",
|
||||
icone: HardDrive,
|
||||
cor: "text-copper",
|
||||
explicacao:
|
||||
"Ya están conectados a la memoria desde donde se lee el firmware. Usarlos como GPIO común normalmente bloquea el chip o corrompe la ejecución. En módulos con flash interna ni siquiera llegan a los pines del encapsulado.",
|
||||
combina: (avisos) =>
|
||||
/(flash|psram)/i.test(avisos) &&
|
||||
/(dedicado|utilizado por la mem|no debe|no se recomienda|no recomendado|connected to|dedicated to)/i.test(avisos),
|
||||
},
|
||||
{
|
||||
id: "strapping",
|
||||
titulo: "Strapping (modo de arranque)",
|
||||
icone: Power,
|
||||
cor: "text-gold",
|
||||
explicacao:
|
||||
"El chip lee el nivel lógico de estos pines en el instante del reset para decidir cómo inicializarse. Pueden usarse después del arranque, pero el circuito externo no debe forzar el nivel incorrecto durante el reset, de lo contrario la placa no iniciará o entrará en modo de descarga inesperadamente.",
|
||||
combina: (avisos, cats) =>
|
||||
cats.includes("Strapping") ||
|
||||
/strapping|modo de arranque|modo de inicialización|boot mode/i.test(avisos),
|
||||
},
|
||||
{
|
||||
id: "debug",
|
||||
titulo: "Grabación y depuración",
|
||||
icone: Bug,
|
||||
cor: "text-accent",
|
||||
explicacao:
|
||||
"Son la UART de grabación y las líneas de JTAG. Siguen utilizables como GPIO, pero al reutilizarlos pierde la posibilidad de grabar y depurar la placa sin desconectar lo que esté conectado allí.",
|
||||
combina: (avisos, cats) => /depuración|grabación|debugging/i.test(avisos) || cats.includes("JTAG"),
|
||||
},
|
||||
{
|
||||
id: "usb",
|
||||
titulo: "USB nativo",
|
||||
icone: Usb,
|
||||
cor: "text-accent",
|
||||
explicacao:
|
||||
"Salen de fábrica conectados al USB Serial/JTAG interno. Para usarlos como GPIO es necesario desactivar esa función, lo que también elimina la grabación por USB directo.",
|
||||
combina: (avisos) => /usb serial\/jtag|usb_d[+-]/i.test(avisos),
|
||||
},
|
||||
{
|
||||
id: "eletrico",
|
||||
titulo: "No deben quedar flotando",
|
||||
icone: Zap,
|
||||
cor: "text-gold",
|
||||
explicacao:
|
||||
"Requieren un nivel lógico definido por hardware: pull-up externo o circuito RC de retardo. Dejarlos sueltos causa reinicios aleatorios o un arranque inestable.",
|
||||
combina: (avisos) => /flotando|floating/i.test(avisos),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -85,8 +207,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, isEs) {
|
||||
const listaGrupos = isEn ? GRUPOS_EN : isEs ? GRUPOS_ES : 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 +224,13 @@ function derivarGrupos(conexoes) {
|
||||
}).filter((g) => g.pinos.length > 0);
|
||||
}
|
||||
|
||||
export default function PinRestrictions({ conexoes, serieKey }) {
|
||||
export default function PinRestrictions({ conexoes, serieKey, isEn = false, isEs = false, locale }) {
|
||||
if (!conexoes?.length) return null;
|
||||
|
||||
const grupos = derivarGrupos(conexoes);
|
||||
const effectiveIsEn = isEn || locale === "en";
|
||||
const effectiveIsEs = isEs || locale === "es";
|
||||
|
||||
const grupos = derivarGrupos(conexoes, effectiveIsEn, effectiveIsEs);
|
||||
if (!grupos.length) return null;
|
||||
|
||||
const totalPinos = new Set(grupos.flatMap((g) => g.pinos)).size;
|
||||
@@ -115,13 +241,25 @@ 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
|
||||
{effectiveIsEn ? "Pins with usage restrictions" : effectiveIsEs ? "Pines con restricción de uso" : "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.
|
||||
{effectiveIsEn ? (
|
||||
<>
|
||||
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.
|
||||
</>
|
||||
) : effectiveIsEs ? (
|
||||
<>
|
||||
No todos los pines del {serieKey} están libres para uso general. {totalPinos} de ellos tienen alguna condición: ya están ocupados por memoria, se leen durante el arranque o solo funcionan como entrada. Conviene comprobarlos antes de cerrar el esquemático.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
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 +269,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 ? (effectiveIsEn ? "pin" : effectiveIsEs ? "pin" : "pino") : (effectiveIsEn ? "pins" : effectiveIsEs ? "pines" : "pinos")}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -150,11 +288,16 @@ 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.
|
||||
{effectiveIsEn ? (
|
||||
"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."
|
||||
) : effectiveIsEs ? (
|
||||
"Estos grupos proceden de los mismos datos que el diagrama de conexiones. Allí podrá consultar pino a pino todas las funciones, el dominio de alimentación y los avisos completos."
|
||||
) : (
|
||||
"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
|
||||
{effectiveIsEn ? "Open pinout diagram" : effectiveIsEs ? "Abrir diagrama de pines" : "Abrir diagrama de pinos"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
+65
-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,35 @@ 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 TIPOS_ES = {
|
||||
resposta: { label: "Respuesta", Icon: Sparkles, cor: "bg-accent text-accent-contrast" },
|
||||
pino: { label: "Pines", Icon: Plug, cor: "bg-accent text-accent-contrast" },
|
||||
pagina: { label: "Página", Icon: FileText, cor: "bg-surface-2 text-ink-soft" },
|
||||
serie: { label: "Serie", Icon: Cpu, cor: "bg-accent-soft text-accent" },
|
||||
framework: { label: "Framework", Icon: Terminal, cor: "bg-teal-soft text-teal" },
|
||||
glossario: { label: "Glosario", Icon: BookOpen, cor: "bg-copper-soft text-copper" },
|
||||
erro: { label: "Error", Icon: AlertTriangle, cor: "bg-gold-soft text-gold" },
|
||||
componente: { label: "Componente", 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"];
|
||||
const EXEMPLOS_ES = ["flash s3", "pines usb 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 +109,14 @@ function Pilula({ children, onClick, forte = false }) {
|
||||
}
|
||||
|
||||
export default function SearchDialog() {
|
||||
const pathname = usePathname() || "";
|
||||
const locale = pathname === "/en" || pathname.startsWith("/en/") ? "en" : (pathname === "/es" || pathname.startsWith("/es/") ? "es" : "pt");
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
|
||||
const TIPOS = isEn ? TIPOS_EN : isEs ? TIPOS_ES : TIPOS_PT;
|
||||
const EXEMPLOS = isEn ? EXEMPLOS_EN : isEs ? EXEMPLOS_ES : EXEMPLOS_DE_BUSCA;
|
||||
|
||||
const [aberto, setAberto] = useState(false);
|
||||
const [montado, setMontado] = useState(false);
|
||||
const [consulta, setConsulta] = useState("");
|
||||
@@ -124,9 +156,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" : isEs ? "/api/busca/es?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 +180,7 @@ export default function SearchDialog() {
|
||||
return () => {
|
||||
cancelado = true;
|
||||
};
|
||||
}, []);
|
||||
}, [isEn, isEs]);
|
||||
|
||||
// Carrega o índice (textos + especificações + pinos) na primeira abertura.
|
||||
useEffect(() => {
|
||||
@@ -182,7 +221,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 +251,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)" : isEs ? "Buscar en 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" : isEs ? "Buscar en 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 +273,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”…" : isEs ? "Pregunte a ESPDocs: “flash s3”, “pines usb 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" : isEs ? "Término de búsqueda" : "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" : isEs ? "Cerrar búsqueda" : "Fechar busca"}
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
@@ -253,7 +291,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:" : isEs ? "Entendido:" : "Entendi:"}</span>
|
||||
{interpretacao.chips.map((c) => (
|
||||
<Pilula key={c.chave} forte>{c.nome}</Pilula>
|
||||
))}
|
||||
@@ -265,7 +303,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:" : isEs ? "Preguntar sobre:" : "Perguntar sobre:") : (isEn ? "Which chip?" : isEs ? "¿Para qué chip?" : "Para qual chip?")}</span>
|
||||
{sugestoes.map((s) => (
|
||||
<Pilula key={s.rotulo} onClick={() => anexar(s.anexar)}>
|
||||
{s.rotulo}
|
||||
@@ -277,36 +315,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." : isEs ? "No se pudo cargar el índice de búsqueda." : "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" : isEs ? "Reintentar" : "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…" : isEs ? "Cargando…" : "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" : isEs ? "Pruebe a preguntar" : "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" : isEs ? "Ir a" : "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}”` : isEs ? `Sin resultados para “${consulta}”` : `Nenhum resultado para “${consulta}”`}</p>
|
||||
<p className="mt-1 text-sm text-muted">{isEn ? "Try “brownout”, “flash s3”, “usb pins c6” or “LVGL”." : isEs ? "Pruebe “brownout”, “flash s3”, “pines usb c6” o “LVGL”." : "Tente “brownout”, “flash s3”, “pinos usb c6” ou “LVGL”."}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -369,10 +407,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" : isEs ? "cerrar" : "fechar"}</span>
|
||||
<span className="ml-auto">{vazia ? (isEn ? "Tip: press / on any page" : isEs ? "Consejo: presione / en cualquier página" : "Dica: pressione / em qualquer página") : `${resultados.length} ${isEn ? "result(s)" : "resultado(s)"}`}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
export default function SeriesTabMenu({ tabs }) {
|
||||
export default function SeriesTabMenu({ tabs, isEn = false, isEs = false, locale }) {
|
||||
const effectiveIsEn = isEn || locale === "en";
|
||||
const effectiveIsEs = isEs || locale === "es";
|
||||
const availableTabs = tabs.filter((tab) => tab.available);
|
||||
const [activeTab, setActiveTab] = useState(availableTabs[0]?.id);
|
||||
const refs = useRef({});
|
||||
@@ -59,7 +61,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={effectiveIsEn ? "Board and diagram" : effectiveIsEs ? "Placa y diagrama" : "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,422 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "ANT",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Conexión de antena de RF (Wi-Fi y Bluetooth)"
|
||||
],
|
||||
"categorias": [
|
||||
"Antena",
|
||||
"RF"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin de RF dedicado. Evite trazar pistas largas o sin acoplamiento de impedancia de 50 ohms."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDDA3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Alimentación analógica de 3.3V"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V (3.0V a 3.6V)",
|
||||
"Suministra energía a los circuitos analógicos y de RF del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDDA3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Alimentación analógica de 3.3V"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V (3.0V a 3.6V)",
|
||||
"Suministra energía a los circuitos analógicos y de RF del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "GPIO0",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO0",
|
||||
"ADC1_CH0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin de entrada analógica ADC1 Canal 0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "GPIO1",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO1",
|
||||
"ADC1_CH1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin 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 a la función SPI MISO (FSPIQ) por defecto durante el arranque de la flash"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "CHIP_EN",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Habilitar el chip (Power-up / Reset)"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Activo en alto. Lleve a nivel alto para iniciar el chip.",
|
||||
"No deje este pin flotando. Use un circuito RC de retardo externo para un arranque estable."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "GPIO3",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"ADC1_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin 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": [
|
||||
"Pin multifuncional: JTAG MTMS, SPI2 MISO y ADC1 Canal 4.",
|
||||
"Puede usarse para depuración JTAG junto con otros pines JTAG."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "GPIO5",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"MTDI",
|
||||
"FSPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin multifuncional: JTAG MTDI y SPI2 Write Protect (FSPIWP)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "VDD3P3_RTC",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Alimentación del dominio RTC e I/Os de bajo consumo"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "GPIO6",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"MTCK",
|
||||
"FSPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin multifuncional: JTAG MTCK y SPI2 Clock (FSPICLK)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "GPIO7",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO7",
|
||||
"MTDO",
|
||||
"FSPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin multifuncional: JTAG MTDO y SPI2 MOSI (FSPID)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO8"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin de strapping para control de arranque.",
|
||||
"Junto con GPIO9, selecciona el modo de arranque del SoC (debe estar en 1 durante el reinicio para Joint Download Boot si GPIO9=0)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO9"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin de strapping principal. Nivel alto (1) en el reinicio activa SPI Boot (predeterminado vía pull-up débil).",
|
||||
"Nivel bajo (0) en el reinicio coloca el chip en modo de descarga UART/SPI."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"FSPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin multifuncional: SPI2 Chip Select 0 (FSPICS0)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "VDD3P3_CPU",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Alimentación digital de la CPU e I/Os correspondientes (3.3V)"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión 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": [
|
||||
"Pin de recepción UART0 (Serial RX por defecto para grabación y monitorización)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "GPIO20",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"U0TXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin de transmisión UART0 (Serial TX por defecto para grabación y monitorización)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Alimentación de entrada analógica de 3.3V"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Conexión externa del cristal oscilador (Salida)"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Conexión externa del cristal oscilador (Entrada)"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Alimentación de entrada analógica de 3.3V"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GND",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Pin de conexión a tierra central (Exposed Pad)"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Debe soldarse adecuadamente al plano de tierra (GND) de la PCB para un rendimiento estable y disipación térmica."
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,643 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "LNA_IN",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Entrada y salida de señales de RF (Wi-Fi y Bluetooth) para la antena"
|
||||
],
|
||||
"categorias": [
|
||||
"Antena"
|
||||
],
|
||||
"avisos": [
|
||||
"Consulte la sección 2.4 de la hoja de datos para más detalles sobre pines analógicos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del 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 el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"En realidad, este pin no determina el modo de arranque, pero se recomienda conectarlo con un pull-up para evitar transitorios (consulte la sección 3.1 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "CHIP_EN",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Habilitar el chip"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Llevar este pin a nivel alto habilitará el funcionamiento del chip",
|
||||
"Llevar este pin a nivel bajo deshabilitará el funcionamiento del chip",
|
||||
"No deje este pin flotando, utilice una resistencia pull-up externa"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "GPIO3",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"ADC1_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin 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": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "MTDI",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_RTC"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"ADC2_CH0",
|
||||
"FSPIWP",
|
||||
"MTDI"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"ADC",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "VDD3P3_RTC",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio de bajo consumo y parte del dominio digital"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "12",
|
||||
"nome": "MTCK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"FSPICLK",
|
||||
"MTCK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "MTDO",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO7",
|
||||
"FSPID",
|
||||
"MTDO"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO8"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Utilizado para controlar el modo de arranque del chip (consulte la sección 3.1 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO9"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado para controlar el modo de arranque del chip (consulte la sección 3.1 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"FSPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "VDD3P3_CPU",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio digital"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "VDD_SPI",
|
||||
"tipo": "power",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"Entrada/salida de la alimentación de la flash interna/externa",
|
||||
"GPIO11"
|
||||
],
|
||||
"categorias": [
|
||||
"Power",
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip",
|
||||
"Solo puede utilizarse como GPIO si la memoria flash está alimentada por una fuente externa"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "SPIHD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"SPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "SPIWP",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"SPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "SPICS0",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO14",
|
||||
"SPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "SPICLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO15",
|
||||
"SPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "SPID",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO16",
|
||||
"SPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "SPIQ",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"SPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GPIO18",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO18",
|
||||
"USB_D-"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Por defecto, este pin se utiliza para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "GPIO19",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO19",
|
||||
"USB_D+"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Por defecto, este pin se utiliza para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "U0RXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"U0RXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "U0TXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD3P3_CPU"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO21",
|
||||
"U0TXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Entrada/Salida negativa de reloj"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"Consulte la sección 2.3.2 de la hoja de datos para más detalles sobre pines analógicos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Entrada/Salida positiva de reloj"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"Consulte la sección 2.3.2 de la hoja de datos para más detalles sobre pines analógicos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "VDDA",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": [
|
||||
"Referencia eléctrica del circuito (tierra)"
|
||||
],
|
||||
"categorias": [
|
||||
"GND"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,944 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "VDDA6",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": [
|
||||
"Referencia eléctrica del circuito (tierra)"
|
||||
],
|
||||
"categorias": [
|
||||
"GND"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDDA7",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Entrada/Salida negativa de reloj"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"Consulte la sección 2.3.3 de la hoja de datos para más detalles sobre pines analógicos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Entrada/Salida positiva de reloj"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"Consulte la sección 2.3.3 de la hoja de datos para más detalles sobre pines analógicos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "VDDA8",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "CHIP_PU",
|
||||
"tipo": "analog",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"Habilitar el chip"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Llevar este pin a nivel alto habilitará el funcionamiento del chip",
|
||||
"Llevar este pin a nivel bajo deshabilitará el funcionamiento del chip",
|
||||
"No deje este pin flotando, utilice una resistencia pull-up externa"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio digital de bajo consumo"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del 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 el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"La función I2C_SDA está disponible en el modo de bajo consumo (LP)",
|
||||
"Pin utilizado para depuración",
|
||||
"Utilizado para controlar la frecuencia del cristal oscilador del chip (consulte la sección 3.5 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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 el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"La función I2C_SDA está disponible en el modo de bajo consumo (LP)",
|
||||
"Pin utilizado para depuración",
|
||||
"Utilizado para controlar la temporización de SDIO Slave (consulte la sección 3.2 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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 el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO6",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO6",
|
||||
"LP_GDIO6",
|
||||
"ADC1_CH5",
|
||||
"FSPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Low Power",
|
||||
"ADC",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO7",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO7",
|
||||
"FSPID",
|
||||
"SDIO_DATA1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Utilizado para controlar la fuente de señales JTAG (consulte la sección 3.4 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO8",
|
||||
"SDIO_DATA0",
|
||||
"PAD_COMP0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO9",
|
||||
"SDIO_CLK",
|
||||
"PAD_COMP1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"FSPICS0",
|
||||
"SDIO_CMD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "U0TXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO11",
|
||||
"U0TXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "U0RXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"U0RXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "GPIO13",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"USB_D-",
|
||||
"SDIO_DATA3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Por defecto, este pin se utiliza para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "GPIO14",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO14",
|
||||
"USB_D+",
|
||||
"SDIO_DATA4"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno para USB activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con el pull-up interno para USB activado",
|
||||
"Por defecto, este pin se utiliza para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "VDDPST2",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio digital de alto rendimiento y parte del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "SPICS1",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO15",
|
||||
"SPICS1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "SPICS0",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO16",
|
||||
"SPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "SPIQ",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"SPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "SPIWP",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO18",
|
||||
"SPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "VDD_SPI",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Salida de alimentación para la flash externa",
|
||||
"GPIO19"
|
||||
],
|
||||
"categorias": [
|
||||
"Power",
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip",
|
||||
"Solo puede utilizarse como GPIO si la memoria flash externa está alimentada por una fuente externa"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "SPIHD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"SPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "SPICLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO21",
|
||||
"SPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "SPID",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO22",
|
||||
"SPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "GPIO23",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST3"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO23"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "34",
|
||||
"nome": "GPIO24",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST3"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO24"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "35",
|
||||
"nome": "GPIO25",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST3"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO25"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Utilizado para controlar la temporización de SDIO Slave (consulte la sección 3.4 de la hoja de datos para mais detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "36",
|
||||
"nome": "GPIO26",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST3"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO26"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Utilizado para controlar el modo de arranque del chip (consulte la sección 3.1 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "37",
|
||||
"nome": "GPIO27",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST3"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO27"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado para controlar el modo de arranque del chip (consulte la sección 3.1 de la hoja de datos para más detalles)",
|
||||
"Utilizado para controlar la emisión de mensajes de la ROM en UART0 (consulte la sección 3.3 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "38",
|
||||
"nome": "GPIO28",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST3"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO28"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado para controlar el modo de arranque del chip (consulte la sección 3.1 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "39",
|
||||
"nome": "VDDPST3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio digital de alto rendimiento"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "40",
|
||||
"nome": "VDDA1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "41",
|
||||
"nome": "VDDA2",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "42",
|
||||
"nome": "ANT_2G",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Conexión de la antena RF para la banda de 2 GHz"
|
||||
],
|
||||
"categorias": [
|
||||
"Antena"
|
||||
],
|
||||
"avisos": [
|
||||
"Consulte la sección 2.4 de la hoja de datos para más detalles sobre pines analógicos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "43",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": [
|
||||
"Referencia eléctrica del circuito (tierra)"
|
||||
],
|
||||
"categorias": [
|
||||
"GND"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "44",
|
||||
"nome": "VDDA3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "44",
|
||||
"nome": "VDDA4",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "45",
|
||||
"nome": "VDDA5",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "47",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": [
|
||||
"Referencia eléctrica del circuito (tierra)"
|
||||
],
|
||||
"categorias": [
|
||||
"GND"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "48",
|
||||
"nome": "ANT_5G",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Conexión de la antena RF para la banda de 5 GHz"
|
||||
],
|
||||
"categorias": [
|
||||
"Antena"
|
||||
],
|
||||
"avisos": [
|
||||
"Consulte la sección 2.4 de la hoja de datos para más detalles sobre pines analógicos"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,841 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "ANT",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Conexión de la antena RF"
|
||||
],
|
||||
"categorias": [
|
||||
"Antena"
|
||||
],
|
||||
"avisos": [
|
||||
"Consulte la sección 2.4 de la hoja de datos para más detalles sobre pines analógicos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDDA3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDDA3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "4",
|
||||
"nome": "CHIP_PU",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Habilitar el chip"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Llevar este pin a nivel alto habilitará el funcionamiento del chip",
|
||||
"Llevar este pin a nivel bajo deshabilitará el funcionamiento del chip",
|
||||
"No deje este pin flotando, utilice una resistencia pull-up externa"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio digital de bajo consumo y parte del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del 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 el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin 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 el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin 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 el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Pin utilizado para depuración",
|
||||
"Utilizado para controlar la temporización de SDIO Slave (consulte la sección 3.2 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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 el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Pin utilizado para depuración",
|
||||
"Utilizado para controlar la temporización de SDIO Slave (consulte la sección 3.2 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"La función I2C_SDA está disponible en el modo de bajo consumo (LP)",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"La función I2C_SDA está disponible en el modo de bajo consumo (LP)",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "14",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO8"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Utilizado para controlar el modo de arranque del chip (consulte la sección 3.1 de la hoja de datos para más detalles)",
|
||||
"Utilizado para controlar la emisión de mensajes de la ROM en UART0 (consulte la sección 3.3 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "15",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO9"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado para controlar el modo de arranque del chip (consulte la sección 3.1 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "16",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO10"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "17",
|
||||
"nome": "GPIO11",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO11"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "GPIO12",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"USB_D-"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Por defecto, este pin se utiliza para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "GPIO13",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"USB_D+"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Por defecto, este pin se utiliza para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "SPICS0",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO24",
|
||||
"SPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "SPIQ",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO25",
|
||||
"SPIQ"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "22",
|
||||
"nome": "SPIWP",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO26",
|
||||
"SPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "VDD_SPI",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada/Salida de alimentación para la memoria flash",
|
||||
"GPIO27"
|
||||
],
|
||||
"categorias": [
|
||||
"Power",
|
||||
"GPIO"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip",
|
||||
"Solo puede utilizarse como GPIO si la memoria flash externa está alimentada por una fuente externa"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "SPIHD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO28",
|
||||
"SPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "SPICLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO29",
|
||||
"SPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "SPID",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO30",
|
||||
"SPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado por la memoria flash SPI",
|
||||
"No se recomienda utilizar este pin como GPIO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "GPIO15",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO15"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Utilizado para controlar la fuente de señales JTAG (consulte la sección 3.4 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "VDDA2",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio digital de alto rendimiento"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "U0TXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO16",
|
||||
"U0TXD",
|
||||
"FSPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "U0RXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"U0RXD",
|
||||
"FSPICS1"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "SDIO_CMD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO18",
|
||||
"SDIO_CMD",
|
||||
"FSPICS2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "SDIO_CLK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO19",
|
||||
"SDIO_CLK",
|
||||
"FSPICS3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "SDIO_DATA0",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"SDIO_DATA0",
|
||||
"FSPICS4"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "34",
|
||||
"nome": "SDIO_DATA1",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO21",
|
||||
"SDIO_DATA1",
|
||||
"FSPICS5"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "35",
|
||||
"nome": "SDIO_DATA2",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO22",
|
||||
"SDIO_DATA2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "36",
|
||||
"nome": "SDIO_DATA3",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO23",
|
||||
"SDIO_DATA3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SD"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará con el pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "37",
|
||||
"nome": "VDDA1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "38",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Entrada/Salida negativa de reloj"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"Consulte la sección 2.4 de la hoja de datos para más detalles sobre pines analógicos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "39",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Entrada/Salida positiva de reloj"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"Consulte la sección 2.4 de la hoja de datos para más detalles sobre pines analógicos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "40",
|
||||
"nome": "VDDA2",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "41",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": [
|
||||
"Referencia eléctrica del circuito (tierra)"
|
||||
],
|
||||
"categorias": [
|
||||
"GND"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,729 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "ANT_2G",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Conexión de antena de RF (Wi-Fi y Bluetooth)"
|
||||
],
|
||||
"categorias": [
|
||||
"Antena",
|
||||
"RF"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin de RF dedicado a 2.4 GHz. Requer casamento de impedância de 50 ohms."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDDA3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Alimentación del dominio analógico de 3.3V"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V (3.0V a 3.6V). Fornece energia para circuitos de RF e clock."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "3",
|
||||
"nome": "VDDA4",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Alimentación del dominio analógico de 3.3V"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión 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 el chip (Power-up / Reset)"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Activo en alto. Lleve a nivel alto para iniciar el chip.",
|
||||
"No deje este pin flotando. Se recomienda usar un circuito RC de retardo externo para un reinicio limpio."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "5",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Alimentación digital de los dominios HP (High Performance) y LP (Low Power)"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión 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": [
|
||||
"Pin multifuncional de bajo consumo. Puede conectarse al 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": [
|
||||
"Pin multifuncional. Conexión del cristal de 32 kHz externo (Salida N) y 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": [
|
||||
"Pin multifuncional: JTAG MTMS, ADC1 Canal 1 y pin de strapping para control de flanco de reloj de SDIO.",
|
||||
"Flotante por defecto durante el reinicio."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "GPIO4",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"MTDI",
|
||||
"ADC1_CH2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"ADC",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin multifuncional: JTAG MTDI, ADC1 Canal 2 y pin de strapping para control de flanco de reloj de SDIO.",
|
||||
"Flotante por defecto durante el reinicio."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "GPIO5",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"MTCK",
|
||||
"ADC1_CH3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"JTAG",
|
||||
"ADC"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin 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": [
|
||||
"Pin multifuncional JTAG MTDO."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "13",
|
||||
"nome": "GPIO25",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO25",
|
||||
"SDIO_CMD",
|
||||
"FSPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SDIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin 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": [
|
||||
"Pin 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": [
|
||||
"Pin 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": [
|
||||
"Pin 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": [
|
||||
"Pin 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": [
|
||||
"Pin 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": [
|
||||
"Pin dedicado para Chip Select 1 de la interfaz de memoria SPI Flash/PSRAM."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "GPIO15",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO15",
|
||||
"SPICS0"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin dedicado para Chip Select 0 de la interfaz de memoria SPI Flash."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "21",
|
||||
"nome": "VDDPST2",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Alimentación del dominio digital HP (High Performance)"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión 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": [
|
||||
"Pin de datos Q (MISO) de la interfaz de memoria flash SPI."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "GPIO17",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO17",
|
||||
"SPIWP"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin de protección contra escritura (Write Protect) de la interfaz de memoria flash SPI."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "VDD_SPI",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Tensión de salida LDO gerada a partir de VDDPST2 para lalimentar a flash e PSRAM"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión de salida configurable por software de acuerdo con las especificaciones de la flash interna/externa (normalmente 3.3V o 1.8V).",
|
||||
"No debe usarse como fuente general de energía de alta corriente."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GPIO19",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO19",
|
||||
"SPIHD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin de control de Hold de la interfaz de memoria flash SPI."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "GPIO20",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO20",
|
||||
"SPICLK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin de señal de reloj de la interfaz de memoria flash SPI."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "GPIO21",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDD_SPI",
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO21",
|
||||
"SPID"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin de datos D (MOSI) de la interfaz de memoria flash SPI."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "GPIO12",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO12",
|
||||
"USB_D-"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin de señal negativa del transceptor USB Serial/JTAG integrado."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "GPIO13",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO13",
|
||||
"USB_D+"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin de señal positiva del transceptor USB Serial/JTAG integrado.",
|
||||
"Dispone de pull-up integrado activado por defecto en el arranque del 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": [
|
||||
"Pin de strapping para selección del modo de arranque y control de emisión de mensajes de la ROM.",
|
||||
"Flotante por defecto durante el reinicio. Nivel alto (1) activa la emisión del registro de arranque."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO9"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Pin de strapping principal para selección del modo de arranque.",
|
||||
"Equipado con pull-up débil integrado. Nivel alto (1) en el reinicio activa SPI Boot (carga desde la flash). Nivel bajo (0) fuerza el modo Download."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "GPIO10",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO10",
|
||||
"U0RXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Recepción serial UART0 (Serial RX para grabación del firmware externa y depuración)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "34",
|
||||
"nome": "GPIO11",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO11",
|
||||
"U0TXD"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART"
|
||||
],
|
||||
"avisos": [
|
||||
"Transmisión serial UART0 (Serial TX para grabación del firmware externa y depuración)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": [
|
||||
"Pin de strapping para selección de la fuente de señales JTAG (arranque temprano).",
|
||||
"Sin resistencias de pull internas en el reinicio. Debe mantenerse estable mediante circuito externo si se utiliza."
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "37",
|
||||
"nome": "VDDA1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Alimentación del dominio analógico de 3.3V"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "38",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Conexión externa del cristal oscilador de 40 MHz (Salida N)"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "39",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Conexión externa del cristal oscilador de 40 MHz (Entrada P)"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "40",
|
||||
"nome": "VDDA2",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Alimentación del dominio analógico de 3.3V"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "41",
|
||||
"nome": "GND",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Pin de conexión a tierra central (Exposed Pad)"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Debe soldarse adecuadamente al plano de masa (GND) de la PCB para un control de RF y térmico estable."
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,603 @@
|
||||
[
|
||||
{
|
||||
"numero": "1",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "2",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del 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 el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "6",
|
||||
"nome": "MTDO",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO3",
|
||||
"FSPIHD",
|
||||
"ADC1_CH2",
|
||||
"MTDO"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"ADC",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "7",
|
||||
"nome": "MTCK",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO4",
|
||||
"FSPICLK",
|
||||
"ADC1_CH3",
|
||||
"MTCK"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"ADC",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "8",
|
||||
"nome": "MTDI",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO5",
|
||||
"FSPID",
|
||||
"ADC1_CH4",
|
||||
"MTDI"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"ADC",
|
||||
"JTAG"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "9",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio de E/S"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "10",
|
||||
"nome": "GPIO8",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO8"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Utilizado para controlar el modo de arranque del chip (consulte la sección 3.1 de la hoja de datos para más detalles)",
|
||||
"Utilizado para controlar la emisión de mensajes de la ROM en UART0 (consulte la sección 3.3 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "11",
|
||||
"nome": "GPIO9",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST1"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO9"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Utilizado para controlar el modo de arranque del chip (consulte la sección 3.1 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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 el chip"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Llevar este pin a nivel alto habilitará el funcionamiento del chip",
|
||||
"Llevar este pin a nivel bajo deshabilitará el funcionamiento del chip",
|
||||
"No deje este pin flotando, utilice una resistencia pull-up externa"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "18",
|
||||
"nome": "VBAT",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico o de la batería"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "19",
|
||||
"nome": "VDDA_PMU",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "20",
|
||||
"nome": "VDDPST1",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio de E/S"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del 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": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "23",
|
||||
"nome": "U0TXD",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO24",
|
||||
"U0TXD",
|
||||
"FSPICS2"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"UART",
|
||||
"SPI"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada con pull-up interno activado",
|
||||
"Pin utilizado para depuración"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "24",
|
||||
"nome": "GPIO25",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO24",
|
||||
"FSPICS3"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"Strapping"
|
||||
],
|
||||
"avisos": [
|
||||
"Durante el reinicio, este pin estará configurado como entrada",
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Utilizado para controlar la fuente de señales JTAG (consulte la sección 3.3 de la hoja de datos para más detalles)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "25",
|
||||
"nome": "GPIO26",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO26",
|
||||
"FSPICS4",
|
||||
"USB_D-"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada",
|
||||
"Por defecto, este pin se utiliza para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "26",
|
||||
"nome": "GPIO27",
|
||||
"tipo": "io",
|
||||
"alimentacao": [
|
||||
"VDDPST2"
|
||||
],
|
||||
"funcoes": [
|
||||
"GPIO27",
|
||||
"FSPICS5",
|
||||
"USB_D+"
|
||||
],
|
||||
"categorias": [
|
||||
"GPIO",
|
||||
"SPI",
|
||||
"USB"
|
||||
],
|
||||
"avisos": [
|
||||
"Tras el reinicio, este pin estará configurado como entrada con el pull-up interno para USB activado",
|
||||
"Por defecto, este pin se utiliza para USB Serial/JTAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "27",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "28",
|
||||
"nome": "XTAL_N",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Entrada/Salida negativa de reloj"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"Consulte la sección 2.3.2 de la hoja de datos para más detalles sobre pines analógicos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "29",
|
||||
"nome": "XTAL_P",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Entrada/Salida positiva de reloj"
|
||||
],
|
||||
"categorias": [
|
||||
"Clock"
|
||||
],
|
||||
"avisos": [
|
||||
"Consulte la sección 2.3.2 de la hoja de datos para más detalles sobre pines analógicos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "30",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "31",
|
||||
"nome": "VDD3P3",
|
||||
"tipo": "power",
|
||||
"funcoes": [
|
||||
"Entrada de alimentación del dominio analógico"
|
||||
],
|
||||
"categorias": [
|
||||
"Power"
|
||||
],
|
||||
"avisos": [
|
||||
"Tensión recomendada: 3.3V",
|
||||
"Tensión mínima recomendada: 3.0V",
|
||||
"Tensión máxima recomendada: 3.6V",
|
||||
"Consulte la sección 2.5 de la hoja de datos para más detalles sobre la alimentación del chip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "32",
|
||||
"nome": "ANT",
|
||||
"tipo": "analog",
|
||||
"funcoes": [
|
||||
"Conexión de la antena RF"
|
||||
],
|
||||
"categorias": [
|
||||
"Antena"
|
||||
],
|
||||
"avisos": [
|
||||
"Consulte la sección 2.4 de la hoja de datos para más detalles sobre pines analógicos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"numero": "33",
|
||||
"nome": "GND",
|
||||
"tipo": "ground",
|
||||
"funcoes": [
|
||||
"Referencia eléctrica del circuito (tierra)"
|
||||
],
|
||||
"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,411 @@
|
||||
{
|
||||
"ESP-IDF": {
|
||||
"nome": "ESP-IDF",
|
||||
"icone": "⚙️",
|
||||
"nome_completo": "Espressif IoT Development Framework",
|
||||
"descricao": "Framework oficial nativo de Espressif para todos los SoCs ESP32. Basado en FreeRTOS multinúcleo y CMake, ofrece control total del silicio, periféricos, radio y arquitectura de componentes modulares.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Framework Base Oficial",
|
||||
"funcao_principal": "Desarrollo industrial y de alto rendimiento con acceso directo a registros, RTOS en tiempo real y pila completa de protocolos",
|
||||
"caracteristicas": [
|
||||
"Sistema operativo de tiempo real (FreeRTOS SMP multinúcleo)",
|
||||
"Soporte nativo para ESP Component Registry mediante idf_component.yml",
|
||||
"Pila completa de conectividad Wi-Fi 4/6, BLE 5.x, Zigbee y Thread",
|
||||
"Soporte para todos los SoCs (ESP32, S2, S3, C2, C3, C6, H2, P4)",
|
||||
"Gestión avanzada de energía y modos Deep Sleep",
|
||||
"Seguridad robusta: Secure Boot v2, cifrado de flash y criptografía por hardware",
|
||||
"Actualizaciones OTA cifradas con reversión automática",
|
||||
"Cadena de herramientas moderna Clang/GCC, soporte para C++23 y depuración mediante JTAG OpenOCD"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Productos comerciales e industriales de IoT",
|
||||
"Dispositivos con requisitos estrictos de batería y consumo",
|
||||
"Aplicaciones en tiempo real con control preciso de interrupciones",
|
||||
"Sistemas de seguridad con criptografía por hardware",
|
||||
"Gateways multiprotocolo de alto rendimiento"
|
||||
],
|
||||
"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 nube y firmware de Espressif para productos conectados. Permite crear dispositivos IoT sin necesidad de desarrollar backend o aplicaciones móviles desde cero.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Cloud & AIoT Framework",
|
||||
"funcao_principal": "Construcción acelerada de productos inteligentes con aplicación móvil (iOS/Android), nube AWS Serverless y control por voz (Alexa/Google Home)",
|
||||
"caracteristicas": [
|
||||
"Aprovisionamiento Wi-Fi y BLE asistido mediante aplicación oficial",
|
||||
"Generación dinámica de interfaz en la app según los parámetros del firmware",
|
||||
"Integración nativa con Alexa y Google Assistant",
|
||||
"Soporte simultáneo para control local (Local Control vía mDNS/HTTP) y nube",
|
||||
"Panel administrativo (RainMaker Dashboard) para gestión de flotas y OTA",
|
||||
"Compatibilidad nativa con nodos Matter y Bridge de dispositivos",
|
||||
"Biblioteca integrada mediante ESP Component Registry (espressif/esp_rainmaker)"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Electrodomésticos inteligentes y línea blanca conectada",
|
||||
"Iluminación inteligente y enchufes inteligentes para el consumidor final",
|
||||
"Sistemas de climatización (HVAC) y termostatos conectados",
|
||||
"Prototipos de IoT comercial con validación rápida de mercado",
|
||||
"Productos que requieren certificación para Apple Home, Alexa y Google Home"
|
||||
],
|
||||
"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 de Espressif para el nuevo estándar unificado de hogar inteligente Matter (CSA). Permite interoperabilidad directa con Apple HomeKit, Google Home, Alexa y Home Assistant sin intermediarios.",
|
||||
"linguagem": "C++",
|
||||
"tipo": "Smart Home Framework",
|
||||
"funcao_principal": "Desarrollo de dispositivos y puentes inteligentes compatibles con Matter sobre Wi-Fi o Thread",
|
||||
"caracteristicas": [
|
||||
"Soporte completo para Matter over Wi-Fi y Matter over Thread",
|
||||
"Módulos listos para Matter Bridge (puenteando dispositivos Zigbee/BLE a redes Matter)",
|
||||
"Integración nativa con clusters estándar (Light, Switch, Plug, Sensor, Door Lock)",
|
||||
"Aprovisionamiento seguro mediante BLE y código QR",
|
||||
"Soporte para múltiples fabrics simultáneos (control por Apple y Google al mismo tiempo)",
|
||||
"Compatible con ESP32-C6, ESP32-H2 y chips Wi-Fi clásicos (ESP32/S3) con coprocesador Thread"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Lámparas, enchufes e interruptores con certificación Matter",
|
||||
"Cerraduras electrónicas y controles de acceso conectados",
|
||||
"Puentes y pasarelas Matter-to-Zigbee para migración de productos legados",
|
||||
"Sensores ambientales y de presencia compatibles con ecosistemas múltiples",
|
||||
"Dispositivos que exigen interoperabilidad entre Apple HomeKit, Alexa y Google Home"
|
||||
],
|
||||
"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": "Espressif Audio Development Framework. Marco de trabajo completo para procesamiento de audio digital, códecs, transmisión por streaming y desarrollo de altavoces inteligentes.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Framework de Audio y Voz",
|
||||
"funcao_principal": "Creación de flujos de audio flexibles con decodificadores, ecualizadores, mezcladores y compatibilidad con protocolos de streaming",
|
||||
"caracteristicas": [
|
||||
"Arquitectura en pipelines de audio con elementos modulares (Audio Elements)",
|
||||
"Códecs integrados por software y hardware: MP3, AAC, FLAC, WAV, OGG, Opus",
|
||||
"Compatibilidad con códecs de hardware externos vía I2S (ES8388, ES8311, TAS5805M)",
|
||||
"Clientes de streaming de audio: HTTP Live Streaming, Apple AirPlay, DLNA, Icecast",
|
||||
"Integración con micrófonos MEMS para cancelación de eco acústico (AEC)",
|
||||
"Controladores para pantallas y botones en placas como ESP32-LyraT y ESP32-Korvo"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Altavoces inteligentes y asistentes de voz conectados",
|
||||
"Radios por Internet y reproductores de música en red",
|
||||
"Intercomunicadores IP y timbres con audio bidireccional",
|
||||
"Dispositivos de audio Bluetooth con receptor y transmisor A2DP",
|
||||
"Grabadoras y procesadores de sonido ambiental para monitoreo acústico"
|
||||
],
|
||||
"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": "Espressif Speech Recognition Framework. Conjunto de algoritmos de inteligencia artificial para procesamiento de voz local, sin necesidad de conexión a Internet ni envío de audio a la nube.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Framework de Voz e IA",
|
||||
"funcao_principal": "Procesamiento de voz local, detección de palabra de activación (Wake Word) y reconocimiento de comandos de voz fuera de línea",
|
||||
"caracteristicas": [
|
||||
"Detección de palabra de activación (Wake Word Detection - WakeNet) con bajo consumo y alta precisión",
|
||||
"Reconocimiento de comandos de voz fuera de línea (Command Recognition - MultiNet) con cientos de comandos",
|
||||
"Front-end acústico (AFE) para reducción de ruido, supresión de eco acústico (AEC) y formación de haz (Beamforming)",
|
||||
"Optimizado para instrucciones vectoriales en Xtensa LX7 (ESP32-S3) y RISC-V",
|
||||
"Soporte multilingüe para palabras de activación y comandos configurables",
|
||||
"Modelos compactos que caben en la memoria SRAM/PSRAM del microcontrolador"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Electrodomésticos y paneles con control por voz fuera de línea",
|
||||
"Dispositivos de automatización residencial sin dependencia de la nube",
|
||||
"Juguetes interactivos y robots con respuesta por voz inmediata",
|
||||
"Sistemas industriales con comandos de manos libres en entornos ruidosos",
|
||||
"Front-end de audio para captación de voz en altavoces con Alexa/Google integrados"
|
||||
],
|
||||
"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": "Colección de controladores de periféricos, bibliotecas de sensores, actuadores y componentes de software probados para su uso con ESP-IDF.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Biblioteca de Periféricos y Drivers",
|
||||
"funcao_principal": "Acelerar la integración de componentes de hardware (pantallas LCD/OLED, sensores, botones y buses industriales) en ESP-IDF",
|
||||
"caracteristicas": [
|
||||
"Controladores para pantallas LCD (ST7789, ILI9341, GC9A01) y OLED (SSD1306) con aceleración gráfica",
|
||||
"Controladores para sensores de temperatura, humedad, presión (BME280, SHT30) y acelerómetros",
|
||||
"Gestión avanzada de botones con detección de clic simple, doble, pulsación larga y matriz de teclas",
|
||||
"Control de motores BLDC y paso a paso con biblioteca MCPWM dedicada",
|
||||
"Bibliotecas para buses industriales: Modbus Master/Slave, bus CAN/TWAI y RS-485",
|
||||
"Distribución modular a través de ESP Component Registry"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Interfaces hombre-máquina (HMI) con pantallas a color y perillas codificadoras rotativas",
|
||||
"Estaciones meteorológicas y monitoreo ambiental industrial",
|
||||
"Controladores de motores y actuadores para automatización y robótica",
|
||||
"Gateways Modbus/RS-485 para telemetría industrial",
|
||||
"Proyectos que requieren integración rápida de sensores y pantallas comerciales"
|
||||
],
|
||||
"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 comunicación inalámbrica sin conexión desarrollado por Espressif. Permite la transmisión ultrarrápida de paquetes cortos entre dispositivos ESP32 sin necesidad de enrutador Wi-Fi.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Protocolo de Red y Malla",
|
||||
"funcao_principal": "Intercambio de mensajes punto a punto, broadcast y formación de redes en malla de baja latencia y consumo mínimo",
|
||||
"caracteristicas": [
|
||||
"Comunicación directa entre chips sin handshake ni asociación Wi-Fi (latencia típica < 5 ms)",
|
||||
"Cifrado seguro de paquetes mediante claves precompartidas CCMP/AES-128",
|
||||
"Compatible con transmisiones punto a punto, punto a multipunto y broadcast",
|
||||
"Paquetes de carga útil de hasta 250 bytes por trama",
|
||||
"Coexistencia nativa con modo Wi-Fi Station o SoftAP tradicional en el mismo chip",
|
||||
"Soporte para ESP-NOW Mesh para retransmisión de datos en múltiples saltos"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Sensores a batería que despiertan de Deep Sleep, transmiten datos y duermen en < 100 ms",
|
||||
"Controles remotos industriales y de robótica de latencia ultrabaja",
|
||||
"Interruptores inalámbricos y mandos de pared para automatización doméstica",
|
||||
"Redes de sensores agrícolas distribuidas en áreas sin cobertura Wi-Fi",
|
||||
"Sistemas de emergencia y alarmas de disparo instantáneo"
|
||||
],
|
||||
"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 desarrollo de redes Zigbee 3.0 en SoCs Espressif con radio IEEE 802.15.4 (ESP32-H2, ESP32-C6 y ESP32-H4). Integra la pila ZBOSS de DSR.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Smart Home & Mesh",
|
||||
"funcao_principal": "Construcción de redes de automatización ultraligeras y de bajo consumo en topología de malla Zigbee",
|
||||
"caracteristicas": [
|
||||
"Pila certificada Zigbee PRO con especificación Zigbee 3.0 completa (ZBOSS)",
|
||||
"Soporte para roles de Coordinador (Coordinator), Enrutador (Router) y Dispositivo Final (End Device)",
|
||||
"Soporte para dispositivos durmientes de ultra bajo consumo (Sleepy End Devices - SED)",
|
||||
"Clusters estándar de automatización: On/Off, Level Control, Color Control, Temperature Measurement",
|
||||
"Integración con Matter mediante funcionalidad de puente Zigbee-to-Matter (Bridge)",
|
||||
"Coexistencia de radio con Wi-Fi y Bluetooth en el ESP32-C6"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Sensores de puerta/ventana, presencia y temperatura que funcionan años con pilas botón",
|
||||
"Lámparas inteligentes y bombillas que forman la red en malla Zigbee",
|
||||
"Coordinadores de red Zigbee para integración directa con Home Assistant (ZHA/Zigbee2MQTT)",
|
||||
"Enchufes inteligentes y relés empotrables con reporte de energía",
|
||||
"Puentes y pasarelas de automatización residencial industrial"
|
||||
],
|
||||
"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": "Plataforma de desarrollo para aplicaciones de visión artificial y procesamiento de imágenes, con soporte para cámaras DVP y MIPI CSI en SoCs como ESP32-S3 y ESP32-P4.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Visión por Computadora e IA",
|
||||
"funcao_principal": "Detección de rostros, identificación biométrica, detección de personas y reconocimiento visual en el borde",
|
||||
"caracteristicas": [
|
||||
"Modelos integrados para detección de rostros humanos (Human Face Detection)",
|
||||
"Reconocimiento e identificación facial con registro local de usuarios autorizados",
|
||||
"Detección de presencia humana (Human Face/Body Detection)",
|
||||
"Controladores optimizados para sensores de cámara OmniVision (OV2640, OV3660, OV5640)",
|
||||
"Aceleración mediante instrucciones SIMD vectoriales en ESP32-S3 y ESP32-P4",
|
||||
"Transmisión de video vía servidor HTTP/WebSocket MJPEG en Wi-Fi local"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Timbres con video y cámaras de seguridad conectadas con IA local",
|
||||
"Control de acceso y cerraduras inteligentes con reconocimiento biométrico facial",
|
||||
"Sensores de ocupación de salas y conteo de personas sin envío de imágenes a la nube",
|
||||
"Inspección visual básica y lectura de códigos QR en líneas de producción",
|
||||
"Juguetes inteligentes y dispositivos interactivos con seguimiento de personas"
|
||||
],
|
||||
"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 núcleos optimizados de redes neuronales de Espressif. Sirve como capa base de aceleración de hardware para TensorFlow Lite for Microcontrollers y otros motores de inferencia.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Biblioteca Especializada de IA",
|
||||
"funcao_principal": "Aceleración de inferencia de redes neuronales profundas con cuantización int8 y punto flotante en Xtensa y RISC-V",
|
||||
"caracteristicas": [
|
||||
"Núcleos optimizados en ensamblador con extensiones vectoriales e instrucciones SIMD",
|
||||
"Operaciones aceleradas: convoluciones 2D (Conv2D), Depthwise Conv2D, Fully Connected y Pooling",
|
||||
"Integración directa como backend de aceleración para TensorFlow Lite Micro (TFLite Micro)",
|
||||
"Aumento de velocidad de hasta 3x a 5x en comparación con implementaciones estándar de referencia en C",
|
||||
"Soporte para operaciones con cuantización simétrica int8 para máxima eficiencia de memoria",
|
||||
"Código abierto disponible en GitHub y ESP Component Registry"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Modelos TinyML para mantenimiento predictivo y análisis de vibraciones mecánicas",
|
||||
"Detección de anomalías en señales acústicas e industriales",
|
||||
"Clasificación de audio y eventos sonoros (rotura de cristales, llanto de bebé, disparos)",
|
||||
"Reconocimiento de gestos mediante acelerómetros y sensores IMU de 6 ejes",
|
||||
"Inferencia de redes convolucionales compactas para visión en el borde"
|
||||
],
|
||||
"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 procesamiento digital de señales (DSP) para SoCs ESP32. Proporciona implementaciones matemáticas de alto rendimiento optimizadas a nivel de ensamblador.",
|
||||
"linguagem": "C / C++",
|
||||
"tipo": "Biblioteca Especializada de Señales",
|
||||
"funcao_principal": "Ejecución de cálculos matemáticos pesados como FFT, transformadas, filtrado digital IIR/FIR y operaciones con matrices",
|
||||
"caracteristicas": [
|
||||
"Transformadas Rápidas de Fourier (Radix-2 y Radix-4 FFT) en punto flotante y entero",
|
||||
"Filtros digitales FIR e IIR optimizados para audio y procesamiento de sensores",
|
||||
"Operaciones matriciales (multiplicación, inversión, transposición) con aceleración vectorial",
|
||||
"Generación de señales, funciones de correlación cruzada y cálculo de densidad espectral",
|
||||
"Optimizaciones específicas para FPU e instrucciones vectoriales de Xtensa LX7 y RISC-V",
|
||||
"Documentación completa con benchmarks de ciclos de reloj para cada función"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Ecualización y filtrado de audio en tiempo real en sistemas de altavoces",
|
||||
"Análisis espectral y detección de frecuencias dominantes en mantenimiento predictivo",
|
||||
"Procesamiento de señales biomédicas (ECG, PPG, EEG) en dispositivos de salud",
|
||||
"Filtrado digital de ruido en sensores analógicos de alta precisión",
|
||||
"Algoritmos de control avanzado (filtros de Kalman) para navegación y robótica"
|
||||
],
|
||||
"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": "Ecosistema oficial de soporte para el lenguaje Rust en chips ESP32 (desarrollado por Espressif). Ofrece seguridad de memoria sin garbage collector, con opción de runtime bare-metal o sobre ESP-IDF.",
|
||||
"linguagem": "Rust",
|
||||
"tipo": "Lenguaje y Framework Moderno",
|
||||
"funcao_principal": "Desarrollo de firmware seguro y de alto rendimiento tanto en modo bare-metal (no_std) como con acceso al ecosistema estándar (std / esp-idf-svc)",
|
||||
"caracteristicas": [
|
||||
"Seguridad de memoria en tiempo de compilación (sin punteros nulos, buffer overflows ni data races)",
|
||||
"Modo esp-idf-template (std): acceso a Wi-Fi, BLE, HTTP, MQTT y FreeRTOS a través de bindings de ESP-IDF",
|
||||
"Modo bare-metal esp-hal (no_std): código ultraligero y de arranque instantáneo para microcontroladores RISC-V y Xtensa",
|
||||
"Compilador Rust con soporte para arquitecturas Xtensa y RISC-V (instalación sencilla mediante espup)",
|
||||
"Soporte completo para concurrencia asíncrona moderna con async/await y el executor Embassy",
|
||||
"Ecosistema en rápida expansión mantenido activamente por ingenieros de Espressif"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Dispositivos conectados con requisitos críticos de seguridad de memoria y estabilidad",
|
||||
"Firmwares que no pueden sufrir fallos de segmentación o desbordamientos en campo",
|
||||
"Sistemas industriales que aprovechan concurrencia segura con async/await",
|
||||
"Proyectos de investigación y productos comerciales de vanguardia",
|
||||
"Desarrolladores con experiencia previa en Rust que ingresan al mundo de los sistemas embebidos"
|
||||
],
|
||||
"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": "El core oficial de Arduino para ESP32 (arduino-esp32) mantenido por Espressif. Facilita enormemente el inicio de nuevos proyectos combinando la simplicidad de la API de Arduino con el rendimiento de FreeRTOS.",
|
||||
"linguagem": "C++",
|
||||
"tipo": "Framework Alternativo Popular",
|
||||
"funcao_principal": "Prototipado rápido, proyectos educativos y desarrollo de productos que reutilizan miles de bibliotecas comunitarias de Arduino",
|
||||
"caracteristicas": [
|
||||
"Funciones familiares de Arduino (setup, loop, pinMode, digitalWrite, analogRead)",
|
||||
"Ejecuta internamente sobre ESP-IDF y FreeRTOS (multitarea preventiva disponible bajo cuerda)",
|
||||
"Ecosistema masivo con decenas de miles de bibliotecas para sensores, pantallas y actuadores",
|
||||
"Soporte nativo para Wi-Fi, Bluetooth LE, servidores web asíncronos y actualizaciones OTA",
|
||||
"Compatible con Arduino IDE 2.x, PlatformIO y Visual Studio Code",
|
||||
"Soporte para casi todas las placas de desarrollo comerciales disponibles en el mercado"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Prototipos de concepto (Proof-of-Concept) y validación rápida de ideas",
|
||||
"Proyectos Maker, robótica estudiantil y proyectos de fin de carrera",
|
||||
"Integraciones de hardware comercial con bibliotecas ya existentes para Arduino",
|
||||
"Dispositivos que no requieren personalización profunda del sistema operativo de bajo nivel",
|
||||
"Enseñanza de programación de microcontroladores y electrónica digital"
|
||||
],
|
||||
"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": "Implementación optimizada y eficiente del lenguaje Python 3 diseñada específicamente para ejecutarse en microcontroladores y sistemas con restricciones de recursos.",
|
||||
"linguagem": "Python",
|
||||
"tipo": "Lenguaje e Intérprete Dinámico",
|
||||
"funcao_principal": "Desarrollo interactivo y prototipado ágil en Python con terminal interactivo REPL y sistema de archivos integrado",
|
||||
"caracteristicas": [
|
||||
"Sintaxis completa y moderna de Python 3 con tipos de datos estándar y manejo de excepciones",
|
||||
"Terminal interactivo (REPL) en puerto serie para probar comandos y periféricos en tiempo real sin recompilar",
|
||||
"Módulos nativos para control de hardware: machine (Pin, ADC, PWM, I2C, SPI), network (Wi-Fi), bluetooth",
|
||||
"Sistema de archivos integrado en memoria Flash (LittleFS) accesible como disco virtual",
|
||||
"Soporte para concurrencia asíncrona mediante el módulo uasyncio",
|
||||
"Compatibilidad con IDEs como Thonny, Visual Studio Code y herramientas de subida como mpremote"
|
||||
],
|
||||
"casos_uso": [
|
||||
"Educación y enseñanza de programación y conceptos de IoT",
|
||||
"Pruebas interactivas y diagnóstico de placas directamente en el banco de trabajo",
|
||||
"Dispositivos de monitoreo y recolección de datos donde la velocidad de iteración supera al rendimiento en microsegundos",
|
||||
"Proyectos conectados que se benefician de scripts sencillos y legibles",
|
||||
"Configuración dinámica y ejecución de scripts actualizables sin necesidad de recompilación"
|
||||
],
|
||||
"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,774 @@
|
||||
{
|
||||
"ESP32": {
|
||||
"nome_completo": "ESP32 (Clásico)",
|
||||
"icone": "🔷",
|
||||
"descricao": "El modelo original con procesador dual-core y amplia gama de periféricos",
|
||||
"arquitetura": "Xtensa® LX6 de 32 bits y doble núcleo",
|
||||
"nucleos": "1 (Single-core) o 2 (Dual-core)",
|
||||
"frequencia": "Hasta 240 MHz",
|
||||
"coprocessador_ulp": "Sí",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/192/256",
|
||||
"sha": "SHA-1/256/384/512",
|
||||
"rsa": "Sí (RSA/MPI hasta 4096 bits)",
|
||||
"ecc": "No",
|
||||
"ecdsa": "No",
|
||||
"hmac": "No",
|
||||
"assinatura_digital": "No",
|
||||
"key_manager": "No",
|
||||
"rng": "Sí (TRNG por hardware)",
|
||||
"criptografia_flash": "Sí (AES-256, esquema heredado)",
|
||||
"secure_boot": "V1 (AES, heredado); V2 (RSA-3072, RSA-PSS) a partir de la revisión v3.0 (ECO3)",
|
||||
"protecao_dpa": "No"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, hasta 150 Mbps)",
|
||||
"bluetooth": "Bluetooth 4.2 BR/EDR (Clásico) y Bluetooth LE (modo dual)",
|
||||
"ethernet": "Sí (Ethernet MAC integrado)",
|
||||
"memoria_sram": "520 KB",
|
||||
"memoria_sram_rtc": "16 KB (dividida en RTC FAST y RTC SLOW)",
|
||||
"memoria_rom": "448 KB (para arranque y funciones del núcleo)",
|
||||
"flash_externa": "Hasta 16 MB vía QSPI",
|
||||
"psram_externa": "Hasta 8 MB vía QSPI (en módulos específicos como WROVER)",
|
||||
"gpio": "34",
|
||||
"adc": "2x SAR ADC de 12 bits, hasta 18 canales",
|
||||
"dac": "2x DAC de 8 bits",
|
||||
"touch": "10 canales capacitivos",
|
||||
"uart": "3",
|
||||
"spi": "4 (SPI, HSPI, VSPI - 2 se pueden usar para Flash/PSRAM)",
|
||||
"i2c": "2",
|
||||
"i2s": "2",
|
||||
"pwm": "LED PWM (hasta 16 canales), Motor PWM",
|
||||
"ethernet_mac": "1 (requiere PHY externo)",
|
||||
"can": "1 (CAN 2.0, TWAI®)",
|
||||
"sdio": "1 (SD/SDIO/MMC Host), 1 (SDIO/SPI Slave)",
|
||||
"sensor_hall": "1 (interno)",
|
||||
"sensor_temperatura": "No (retirado de la hoja de datos en 2018; sin controlador en 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 (requiere sonda, ej.: ESP-PROG)",
|
||||
"esp_idf_minimo": "Desde el inicio (v3.x y anteriores)",
|
||||
"arduino_core": "Sí (147 definiciones de placa en el core oficial)",
|
||||
"encapsulamento": "QFN48 (6×6 mm) y QFN48 (5×5 mm)",
|
||||
"modulos": "ESP32-MINI-1, ESP32-PICO-MINI-02, ESP32-PICO-V3, ESP32-PICO-V3-02 y 11 más",
|
||||
"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": "Enfoque en seguridad y bajo consumo, con USB nativo y el único ADC con salida de 13 bits",
|
||||
"arquitetura": "Xtensa® LX7 de 32 bits y núcleo único",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Hasta 240 MHz",
|
||||
"coprocessador_ulp": "Sí (RISC-V ULP coprocessor)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/192/256 com GCM",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Sí (RSA-3072/4096)",
|
||||
"ecc": "No",
|
||||
"ecdsa": "No",
|
||||
"hmac": "Sí (HMAC acelerado por hardware)",
|
||||
"assinatura_digital": "Sí (Digital Signature peripheral)",
|
||||
"key_manager": "No",
|
||||
"rng": "Sí (TRNG por hardware)",
|
||||
"criptografia_flash": "Sí (XTS-AES-128/256)",
|
||||
"secure_boot": "V2 (RSA-3072, RSA-PSS)",
|
||||
"protecao_dpa": "Sí (resistencia DPA de hardware para criptografía)"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, hasta 150 Mbps)",
|
||||
"bluetooth": "No (sin hardware Bluetooth)",
|
||||
"memoria_sram": "320 KB",
|
||||
"memoria_sram_rtc": "16 KB (dividida en RTC FAST y RTC SLOW)",
|
||||
"memoria_rom": "128 KB (para arranque y funciones del núcleo)",
|
||||
"flash_externa": "Hasta 1 GB vía SPI/QSPI/OPI",
|
||||
"psram_externa": "Hasta 1 GB vía SPI/QSPI/OPI",
|
||||
"gpio": "43",
|
||||
"adc": "2x SAR ADC de 13 bits, hasta 20 canales",
|
||||
"dac": "2x DAC de 8 bits",
|
||||
"touch": "14 canales capacitivos",
|
||||
"uart": "2",
|
||||
"spi": "4 (SPI0, SPI1, SPI2, SPI3)",
|
||||
"i2c": "2",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (hasta 8 canales)",
|
||||
"usb": "1x USB 1.1 OTG (Full-Speed a 12 Mbps con PHY integrado)",
|
||||
"lcd": "Interfaz LCD de 8/16 bits",
|
||||
"camera": "Interfaz DVP de 8/16 bits",
|
||||
"sensor_temperatura": "Sí (1 sensor interno, rango -20°C a 110°C)",
|
||||
"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",
|
||||
"esp_idf_minimo": "ESP-IDF v4.2+",
|
||||
"arduino_core": "Sí (core oficial)",
|
||||
"encapsulamento": "QFN56 (7×7 mm)",
|
||||
"modulos": "ESP32-S2-WROOM, ESP32-S2-WROOM-I, ESP32-S2-WROVER, ESP32-S2-MINI-1 y 5 más",
|
||||
"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",
|
||||
"ethernet": "No",
|
||||
"ethernet_mac": "No",
|
||||
"sensor_hall": "No"
|
||||
},
|
||||
"ESP32-S3": {
|
||||
"nome_completo": "ESP32-S3",
|
||||
"icone": "🤖",
|
||||
"descricao": "Procesador dual-core con aceleradores para IA y procesamiento de señales",
|
||||
"arquitetura": "Xtensa® LX7 dual-core de 32 bits con instrucciones vectoriales",
|
||||
"nucleos": "2 (Dual-core)",
|
||||
"frequencia": "Hasta 240 MHz",
|
||||
"coprocessador_ulp": "Sí (RISC-V ULP y FSM coprocessor)",
|
||||
"aceleradores_ia": "Sí (instrucciones vectoriales para acelerar redes neuronales y DSP)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Sí (RSA-3072/4096)",
|
||||
"ecc": "No",
|
||||
"ecdsa": "No",
|
||||
"hmac": "Sí (HMAC acelerado por hardware)",
|
||||
"assinatura_digital": "Sí (Digital Signature peripheral)",
|
||||
"key_manager": "No",
|
||||
"rng": "Sí (TRNG por hardware)",
|
||||
"criptografia_flash": "Sí (XTS-AES-128/256)",
|
||||
"secure_boot": "V2 (RSA-3072, RSA-PSS)",
|
||||
"protecao_dpa": "Sí (resistencia DPA de hardware)"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, hasta 150 Mbps)",
|
||||
"bluetooth": "Bluetooth 5.0 LE y Bluetooth Mesh (soporte de 2 Mbps y largo alcance)",
|
||||
"memoria_sram": "512 KB",
|
||||
"memoria_sram_rtc": "16 KB (dividida en RTC FAST y RTC SLOW)",
|
||||
"memoria_rom": "384 KB (para arranque y funciones del núcleo)",
|
||||
"flash_externa": "Hasta 1 GB vía QSPI u Octal SPI",
|
||||
"psram_externa": "Hasta 1 GB vía QSPI u Octal SPI (hasta 2 MB/8 MB/16 MB en módulos comunes)",
|
||||
"gpio": "45",
|
||||
"adc": "2x SAR ADC de 12 bits, hasta 20 canales",
|
||||
"dac": "No",
|
||||
"touch": "14 canales capacitivos",
|
||||
"uart": "3",
|
||||
"spi": "4 (SPI0, SPI1, SPI2, SPI3)",
|
||||
"i2c": "2",
|
||||
"i2s": "2",
|
||||
"pwm": "LED PWM (hasta 8 canales), MCPWM (para control de motores)",
|
||||
"usb": "1x USB 1.1 OTG (Full-Speed a 12 Mbps) y 1x USB Serial/JTAG integrado",
|
||||
"lcd": "1x interfaz de display LCD de 8 a 16 bits (RGB paralelo/8080)",
|
||||
"camera": "1x interfaz de cámara DVP (8 a 16 bits)",
|
||||
"sdio": "1 (SD/SDIO/MMC Host)",
|
||||
"sensor_temperatura": "Sí (1 sensor 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 de la PSRAM)",
|
||||
"deep_sleep": "7 µA"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 65/85/105°C",
|
||||
"temperatura_armazenamento": "-40°C a 150°C",
|
||||
"depuracao": "USB Serial/JTAG integrado o JTAG externo",
|
||||
"esp_idf_minimo": "ESP-IDF v4.4+",
|
||||
"arduino_core": "Sí (core oficial)",
|
||||
"encapsulamento": "QFN56 (7×7 mm)",
|
||||
"modulos": "ESP32-S3-WROOM-1, ESP32-S3-WROOM-2, ESP32-S3-MINI-1 y 12 más",
|
||||
"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",
|
||||
"ethernet": "No",
|
||||
"ethernet_mac": "No",
|
||||
"sensor_hall": "No"
|
||||
},
|
||||
"ESP32-S31": {
|
||||
"nome_completo": "ESP32-S31",
|
||||
"icone": "🌀",
|
||||
"descricao": "Procesador dual-core RISC-V de alto rendimiento a 320MHz con Wi-Fi 6, Bluetooth 5.4 y Classic, Zigbee/Thread, Matter y aceleración de IA",
|
||||
"arquitetura": "RISC-V dual-core de 32 bits con extensiones vectoriales",
|
||||
"nucleos": "2 (Dual-core)",
|
||||
"frequencia": "Hasta 320 MHz",
|
||||
"coprocessador_ulp": "Sí (RISC-V ULP de ultra bajo consumo)",
|
||||
"aceleradores_ia": "Sí (extensiones vectoriales avanzadas para TinyML, reconocimiento de voz y visión)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256 com GCM",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Sí (RSA-3072/4096)",
|
||||
"ecc": "Sí (ECC HW)",
|
||||
"ecdsa": "Sí (ECDSA HW)",
|
||||
"hmac": "Sí",
|
||||
"assinatura_digital": "Sí (Digital Signature peripheral)",
|
||||
"key_manager": "Sí (Key Manager integrado con eFuse)",
|
||||
"rng": "Sí (TRNG)",
|
||||
"criptografia_flash": "Sí (XTS-AES-128/256)",
|
||||
"secure_boot": "V2 (RSA-3072, ECDSA P-256/384)",
|
||||
"protecao_dpa": "Sí (resistencia DPA de hardware)"
|
||||
},
|
||||
"wifi": "Wi-Fi 6 (802.11ax) 2.4 GHz (retrocompatible con 802.11b/g/n, soporte a OFDMA y TWT)",
|
||||
"bluetooth": "Bluetooth 5.4 LE y Bluetooth Classic (BR/EDR)",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0 y Thread 1.3)",
|
||||
"matter": "Sí (soporte completo como terminal o Matter Bridge)",
|
||||
"memoria_sram": "512 KB (HP SRAM)",
|
||||
"memoria_sram_rtc": "32 KB LP SRAM",
|
||||
"memoria_rom": "512 KB",
|
||||
"flash_externa": "Hasta 1 GB vía Octal SPI (soporte para Flash OPI de alta velocidad)",
|
||||
"psram_externa": "Hasta 1 GB vía Octal SPI (PSRAM OPI de alto ancho de banda)",
|
||||
"gpio": "60",
|
||||
"adc": "2x SAR ADC de 12 bits, hasta 20 canales",
|
||||
"dac": "No",
|
||||
"touch": "14 canales capacitivos táctiles",
|
||||
"uart": "5 (4 UART + 1 LP UART)",
|
||||
"spi": "SPI, QSPI, OPI (múltiples controladores)",
|
||||
"i2c": "3 (2 I2C + 1 LP I2C)",
|
||||
"i2s": "2",
|
||||
"pwm": "LED PWM y MCPWM para control avanzado de motores",
|
||||
"usb": "USB OTG 1.1 Full-Speed y USB Serial/JTAG integrado",
|
||||
"can": "Sim (CAN FD Controller)",
|
||||
"sensor_temperatura": "Sí (sensor de temperatura integrado)",
|
||||
"consumo_energia": {
|
||||
"active": "Consumo optimizado de alto rendimiento configurable",
|
||||
"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": "USB Serial/JTAG integrado y JTAG externo",
|
||||
"esp_idf_minimo": "ESP-IDF v5.4+",
|
||||
"arduino_core": "En desarrollo (previsto tras la maduración en ESP-IDF)",
|
||||
"encapsulamento": "QFN y BGA",
|
||||
"modulos": "ESP32-S31-WROOM, módulos integrados previstos para 2026",
|
||||
"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)",
|
||||
"ethernet": "No",
|
||||
"ethernet_mac": "No",
|
||||
"camera": "Interfaz de cámara paralela DVP / MIPI CSI",
|
||||
"lcd": "Interfaz de display RGB paralelo y MIPI DSI",
|
||||
"sensor_hall": "No",
|
||||
"status_documentacao": "Anunciado por Espressif; especificaciones sujetas a revisión final en la hoja de datos comercial"
|
||||
},
|
||||
"ESP32-C2": {
|
||||
"nome_completo": "ESP32-C2 (ESP8684)",
|
||||
"icone": "🌱",
|
||||
"descricao": "Microcontrolador RISC-V ultra económico y de bajo consumo con Wi-Fi 4 y Bluetooth 5.3 LE",
|
||||
"arquitetura": "RISC-V single-core de 32 bits (RV32IMC)",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Hasta 120 MHz",
|
||||
"seguranca": {
|
||||
"aes": "No",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "Sí (RSA-3072)",
|
||||
"ecc": "Sí (ECC HW acelerado)",
|
||||
"ecdsa": "Sí (ECDSA HW)",
|
||||
"hmac": "No",
|
||||
"assinatura_digital": "No",
|
||||
"key_manager": "No",
|
||||
"rng": "Sí (TRNG por hardware)",
|
||||
"criptografia_flash": "Sí (AES-128-XTS)",
|
||||
"secure_boot": "V2 (RSA-3072 o ECDSA-P256)",
|
||||
"protecao_dpa": "No"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, hasta 72.2 Mbps)",
|
||||
"bluetooth": "Bluetooth 5.3 LE (soporte a 2 Mbps y 1 Mbps, modo publicitario extendido)",
|
||||
"memoria_sram": "272 KB (16 KB para cache)",
|
||||
"memoria_sram_rtc": "No (sin SRAM RTC dedicada; usa SRAM principal)",
|
||||
"memoria_rom": "576 KB (para arranque y funciones del núcleo)",
|
||||
"flash_externa": "Hasta 4 MB en encapsulamiento SiP o externa vía QSPI",
|
||||
"psram_externa": "No",
|
||||
"gpio": "14",
|
||||
"adc": "1x SAR ADC de 12 bits, hasta 5 canales",
|
||||
"dac": "No",
|
||||
"touch": "No",
|
||||
"uart": "2",
|
||||
"spi": "2 (SPI0/1 para Flash interna/externa, SPI2 para propósito general)",
|
||||
"i2c": "1 (Master-only)",
|
||||
"i2s": "No",
|
||||
"pwm": "LED PWM (hasta 6 canales)",
|
||||
"sensor_temperatura": "Sí (1 sensor 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",
|
||||
"esp_idf_minimo": "ESP-IDF v5.0+",
|
||||
"arduino_core": "Sí (core oficial)",
|
||||
"encapsulamento": "QFN24 (4×4 mm) y QFN32 (4×4 mm)",
|
||||
"modulos": "ESP8684-WROOM-02C, ESP8684-WROOM-06C, ESP8684-MINI-1 y 3 más",
|
||||
"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",
|
||||
"coprocessador_ulp": "No",
|
||||
"ethernet": "No",
|
||||
"ethernet_mac": "No",
|
||||
"sensor_hall": "No",
|
||||
"usb": "No"
|
||||
},
|
||||
"ESP32-C3": {
|
||||
"nome_completo": "ESP32-C3",
|
||||
"icone": "💎",
|
||||
"descricao": "Procesador RISC-V de ultra bajo consumo",
|
||||
"arquitetura": "RISC-V single-core de 32 bits (RV32IMC)",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Hasta 160 MHz",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "Sí (RSA-3072)",
|
||||
"ecc": "Sí (ECC HW)",
|
||||
"ecdsa": "Sí (ECDSA HW)",
|
||||
"hmac": "Sí (HMAC acelerado por hardware)",
|
||||
"assinatura_digital": "Sí (Digital Signature peripheral)",
|
||||
"key_manager": "No",
|
||||
"rng": "Sí (TRNG por hardware)",
|
||||
"criptografia_flash": "Sí (XTS-AES-128)",
|
||||
"secure_boot": "V2 (RSA-3072)",
|
||||
"protecao_dpa": "No"
|
||||
},
|
||||
"wifi": "IEEE 802.11 b/g/n (2.4 GHz, hasta 150 Mbps)",
|
||||
"bluetooth": "Bluetooth 5.0 LE y Bluetooth Mesh (soporte a 2 Mbps y largo alcance)",
|
||||
"memoria_sram": "400 KB",
|
||||
"memoria_sram_rtc": "8 KB (RTC FAST SRAM)",
|
||||
"memoria_rom": "384 KB (para arranque y funciones del núcleo)",
|
||||
"flash_externa": "Hasta 16 MB vía QSPI",
|
||||
"psram_externa": "No",
|
||||
"gpio": "22",
|
||||
"adc": "2x SAR ADC de 12 bits, hasta 6 canales",
|
||||
"dac": "No",
|
||||
"touch": "No",
|
||||
"uart": "2",
|
||||
"spi": "3 (SPI0, SPI1, SPI2)",
|
||||
"i2c": "1",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (hasta 6 canales)",
|
||||
"usb": "1x USB Serial/JTAG integrado",
|
||||
"sensor_temperatura": "Sí (1 sensor 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 en el ESP32-C3FN4)",
|
||||
"temperatura_armazenamento": "-40°C a 150°C",
|
||||
"depuracao": "USB Serial/JTAG integrado o JTAG externo",
|
||||
"esp_idf_minimo": "ESP-IDF v4.3+",
|
||||
"arduino_core": "Sí (core oficial)",
|
||||
"encapsulamento": "QFN32 (5×5 mm)",
|
||||
"modulos": "ESP32-C3-WROOM-02, ESP32-C3-MINI-1 y 6 más",
|
||||
"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",
|
||||
"coprocessador_ulp": "No",
|
||||
"ethernet": "No",
|
||||
"ethernet_mac": "No",
|
||||
"sensor_hall": "No"
|
||||
},
|
||||
"ESP32-C5": {
|
||||
"nome_completo": "ESP32-C5",
|
||||
"icone": "📶",
|
||||
"descricao": "El primero con soporte para Wi-Fi 6 dual-band y Bluetooth 6.0, equipado con CPU RISC-V y coprocesador ULP",
|
||||
"arquitetura": "RISC-V single-core de 32 bits (RV32IMC) a 240 MHz",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Hasta 240 MHz",
|
||||
"coprocessador_ulp": "Sí (coprocesador RISC-V ULP de ultra bajo consumo)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Sí (RSA-3072)",
|
||||
"ecc": "Sí (ECC HW)",
|
||||
"ecdsa": "Sí (ECDSA HW)",
|
||||
"hmac": "Sí",
|
||||
"assinatura_digital": "Sí (Digital Signature peripheral)",
|
||||
"key_manager": "Sí (Key Manager integrado)",
|
||||
"rng": "Sí (TRNG por hardware)",
|
||||
"criptografia_flash": "Sí (XTS-AES-128/256)",
|
||||
"secure_boot": "V2 (RSA-3072 / ECDSA)",
|
||||
"protecao_dpa": "Sí (resistencia DPA de hardware)"
|
||||
},
|
||||
"wifi": "Wi-Fi 6 (802.11ax) dual-band (2.4 GHz y 5 GHz), retrocompatible con 802.11a/b/g/n, ancho de banda de 20/40 MHz, OFDMA y TWT",
|
||||
"bluetooth": "Bluetooth 6.0 LE (modo de alta velocidad de 2 Mbps, largo alcance de 125/500 kbps, extensiones publicitarias y BLE Mesh)",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0 y Thread 1.3)",
|
||||
"matter": "Sí (soporte completo para dispositivos Matter sobre Wi-Fi o Thread)",
|
||||
"memoria_sram": "384 KB",
|
||||
"memoria_sram_rtc": "16 KB LP SRAM (en dominio de energía de bajo consumo)",
|
||||
"memoria_rom": "384 KB (para arranque y funciones del núcleo)",
|
||||
"flash_externa": "Hasta 1 GB vía SPI/QSPI/OPI",
|
||||
"psram_externa": "Hasta 1 GB vía SPI/QSPI/OPI",
|
||||
"gpio": "29",
|
||||
"adc": "2x SAR ADC de 12 bits, hasta 8 canales",
|
||||
"dac": "No",
|
||||
"touch": "No",
|
||||
"uart": "3 (2 UART + 1 LP UART)",
|
||||
"spi": "SPI, QSPI, OPI",
|
||||
"i2c": "2 (1 I2C + 1 LP I2C)",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (hasta 6 canales)",
|
||||
"usb": "1x USB Serial/JTAG integrado",
|
||||
"sensor_temperatura": "Sí (1 sensor interno)",
|
||||
"consumo_energia": {
|
||||
"active_wifi": "hasta 377 mA (TX en 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": "USB Serial/JTAG integrado y JTAG externo",
|
||||
"esp_idf_minimo": "ESP-IDF v5.3+",
|
||||
"arduino_core": "En desarrollo (core oficial)",
|
||||
"encapsulamento": "QFN32 (5×5 mm) y QFN48 (6×6 mm)",
|
||||
"modulos": "ESP32-C5-WROOM-1, ESP32-C5-WROOM-1U",
|
||||
"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)",
|
||||
"ethernet": "No",
|
||||
"ethernet_mac": "No",
|
||||
"sensor_hall": "No"
|
||||
},
|
||||
"ESP32-C6": {
|
||||
"nome_completo": "ESP32-C6",
|
||||
"icone": "🌐",
|
||||
"descricao": "Funciones de seguridad avanzada, Wi-Fi 6, Bluetooth 6.0, Zigbee y Thread con soporte para Matter",
|
||||
"arquitetura": "RISC-V single-core de 32 bits (RV32IMAC)",
|
||||
"nucleos": "1 (Single-core) + 1 coprocesador LP RISC-V",
|
||||
"frequencia": "Hasta 160 MHz (CPU principal) + 20 MHz (CPU LP)",
|
||||
"coprocessador_ulp": "Sí (coprocesador RISC-V LP de bajo consumo)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "Sí (RSA-3072)",
|
||||
"ecc": "Sí (ECC HW)",
|
||||
"ecdsa": "Sí (ECDSA HW)",
|
||||
"hmac": "Sí",
|
||||
"assinatura_digital": "Sí (Digital Signature peripheral)",
|
||||
"key_manager": "No",
|
||||
"rng": "Sí (TRNG por hardware)",
|
||||
"criptografia_flash": "Sí (XTS-AES-128)",
|
||||
"secure_boot": "V2 (RSA-3072 / ECDSA)",
|
||||
"protecao_dpa": "No"
|
||||
},
|
||||
"wifi": "Wi-Fi 6 (802.11ax) en 2.4 GHz (retrocompatible con 802.11b/g/n, OFDMA y TWT)",
|
||||
"bluetooth": "Bluetooth 6.0 LE (modo de 2 Mbps, largo alcance y extensiones publicitarias)",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0 y Thread 1.3)",
|
||||
"matter": "Sí (soporte completo)",
|
||||
"memoria_sram": "512 KB",
|
||||
"memoria_sram_rtc": "16 KB LP SRAM",
|
||||
"memoria_rom": "320 KB (para arranque y funciones del núcleo)",
|
||||
"flash_externa": "Hasta 16 MB vía QSPI",
|
||||
"psram_externa": "No",
|
||||
"gpio": "30",
|
||||
"adc": "1x SAR ADC de 12 bits, hasta 7 canales",
|
||||
"dac": "No",
|
||||
"touch": "No",
|
||||
"uart": "3 (2 UART + 1 LP UART)",
|
||||
"spi": "SPI0/1 (memoria), SPI2 (propósito general)",
|
||||
"i2c": "2 (1 I2C + 1 LP I2C)",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (hasta 6 canales), MCPWM",
|
||||
"usb": "1x USB Serial/JTAG integrado",
|
||||
"sdio": "1 (SDIO 2.0 Slave)",
|
||||
"sensor_temperatura": "Sí (1 sensor 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": "USB Serial/JTAG integrado o JTAG externo",
|
||||
"esp_idf_minimo": "ESP-IDF v5.1+",
|
||||
"arduino_core": "Sí (core oficial)",
|
||||
"encapsulamento": "QFN40 (5×5 mm) y QFN32 (5×5 mm)",
|
||||
"modulos": "ESP32-C6-WROOM-1, ESP32-C6-MINI-1 y 4 más",
|
||||
"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",
|
||||
"ethernet": "No",
|
||||
"ethernet_mac": "No",
|
||||
"sensor_hall": "No"
|
||||
},
|
||||
"ESP32-C61": {
|
||||
"nome_completo": "ESP32-C61",
|
||||
"icone": "🛰️",
|
||||
"descricao": "Microcontrolador RISC-V económico de 160MHz con Wi-Fi 6, Bluetooth 6.0 LE y soporte para Flash/PSRAM en el encapsulado",
|
||||
"arquitetura": "RISC-V single-core de 32 bits (RV32IMAC)",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Hasta 160 MHz",
|
||||
"seguranca": {
|
||||
"aes": "No",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "Sí (RSA-3072)",
|
||||
"ecc": "Sí (ECC HW)",
|
||||
"ecdsa": "Sí (ECDSA HW)",
|
||||
"hmac": "Sí",
|
||||
"assinatura_digital": "Sí (Digital Signature peripheral)",
|
||||
"key_manager": "No",
|
||||
"rng": "Sí (TRNG por hardware)",
|
||||
"criptografia_flash": "Sí (XTS-AES-128)",
|
||||
"secure_boot": "V2 (RSA-3072 / ECDSA)",
|
||||
"protecao_dpa": "No"
|
||||
},
|
||||
"wifi": "Wi-Fi 6 (802.11ax) en 2.4 GHz (ancho de banda de 20 MHz, OFDMA, TWT y retrocompatible con 802.11b/g/n)",
|
||||
"bluetooth": "Bluetooth 6.0 LE (modo de 2 Mbps, largo alcance y BLE Mesh)",
|
||||
"zigbee_thread": "No (enfocado en optimización de costes; sin IEEE 802.15.4)",
|
||||
"matter": "Sí (soporte para Matter sobre Wi-Fi)",
|
||||
"memoria_sram": "320 KB",
|
||||
"memoria_sram_rtc": "No (sin SRAM RTC dedicada; usa SRAM principal)",
|
||||
"memoria_rom": "256 KB (para arranque y funciones del núcleo)",
|
||||
"flash_externa": "Hasta 16 MB vía QSPI / Quad SPI Flash integrada en SiP",
|
||||
"psram_externa": "Soporte para Quad SPI PSRAM en SiP (hasta 2 MB/4 MB)",
|
||||
"gpio": "30",
|
||||
"adc": "1x SAR ADC de 12 bits, hasta 6 canales",
|
||||
"dac": "No",
|
||||
"touch": "No",
|
||||
"uart": "3",
|
||||
"spi": "SPI0/1 para memoria, SPI2 para propósito general",
|
||||
"i2c": "1",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (hasta 6 canales)",
|
||||
"usb": "1x USB Serial/JTAG integrado",
|
||||
"sdio": "1 (SDIO 2.0 Slave)",
|
||||
"sensor_temperatura": "Sí (1 sensor 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": "USB Serial/JTAG integrado o JTAG externo",
|
||||
"esp_idf_minimo": "ESP-IDF v5.4+",
|
||||
"arduino_core": "En desarrollo (core oficial)",
|
||||
"encapsulamento": "QFN32 (4×4 mm)",
|
||||
"modulos": "ESP32-C61-WROOM, módulos SiP integrados previstos para 2026",
|
||||
"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",
|
||||
"coprocessador_ulp": "No",
|
||||
"ethernet": "No",
|
||||
"ethernet_mac": "No",
|
||||
"sensor_hall": "No",
|
||||
"status_documentacao": "Anunciado por Espressif como optimización de costes sobre el C6"
|
||||
},
|
||||
"ESP32-P4": {
|
||||
"nome_completo": "ESP32-P4",
|
||||
"icone": "⚡",
|
||||
"descricao": "Alto rendimiento con procesador RISC-V dual-core a 400MHz, aceleradores de IA y ricas interfaces multimedia",
|
||||
"arquitetura": "RISC-V dual-core de 32 bits (HP) + RISC-V single-core de 32 bits (LP)",
|
||||
"nucleos": "2 (Dual-core HP) + 1 (Single-core LP)",
|
||||
"frequencia": "Hasta 400 MHz (núcleos HP) + 40 MHz (núcleo LP)",
|
||||
"coprocessador_ulp": "Sí (RISC-V LP core de bajo consumo)",
|
||||
"aceleradores_ia": "Sí (extensiones vectoriales completas para IA, DSP y códecs de video)",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256 com GCM",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Sí (RSA-3072/4096)",
|
||||
"ecc": "Sí (ECC HW)",
|
||||
"ecdsa": "Sí (ECDSA HW)",
|
||||
"hmac": "Sí",
|
||||
"assinatura_digital": "Sí (Digital Signature peripheral)",
|
||||
"key_manager": "Sí (Key Manager integrado con almacenamiento seguro de claves)",
|
||||
"rng": "Sí (TRNG por hardware)",
|
||||
"criptografia_flash": "Sí (XTS-AES-128/256)",
|
||||
"secure_boot": "V2 (RSA-3072 / ECDSA)",
|
||||
"protecao_dpa": "Sí (resistencia DPA de hardware)"
|
||||
},
|
||||
"wifi": "No (requiere chip complementario como ESP32-C6 para Wi-Fi)",
|
||||
"bluetooth": "No (requiere chip complementario para Bluetooth)",
|
||||
"ethernet": "Sí (Ethernet MAC integrado a 100 Mbps con soporte para RMII)",
|
||||
"memoria_sram": "768 KB",
|
||||
"memoria_sram_rtc": "32 KB LP SRAM (en dominio de bajo consumo)",
|
||||
"memoria_rom": "128 KB (para arranque del sistema)",
|
||||
"flash_externa": "Hasta 1 GB vía Octal SPI",
|
||||
"psram_externa": "Hasta 32 MB PSRAM en encapsulado (hasta 16/32 MB a alta velocidad)",
|
||||
"gpio": "55",
|
||||
"adc": "2x SAR ADC de 12 bits, hasta 16 canales",
|
||||
"dac": "No",
|
||||
"touch": "14 canales capacitivos",
|
||||
"uart": "6 (5 UART + 1 LP UART)",
|
||||
"spi": "Múltiples controladores SPI, QSPI y Octal SPI",
|
||||
"i2c": "3 (2 I2C + 1 LP I2C)",
|
||||
"i2s": "4 (3 I2S + 1 LP I2S)",
|
||||
"pwm": "LED PWM y MCPWM para control de precisión de motores",
|
||||
"usb": "1x USB 2.0 High-Speed OTG (480 Mbps con PHY integrado) y 1x USB 1.1 Full-Speed",
|
||||
"mipi_csi": "2 carriles (1.5 Gbps/carril), compatible con cámaras HD/FHD",
|
||||
"mipi_dsi": "2 carriles (1.5 Gbps/carril), resolución hasta 1080p",
|
||||
"lcd": "1x MIPI DSI (2 carriles, hasta 1.5 Gbps por carril) y 1x interfaz RGB paralela",
|
||||
"camera": "1x MIPI CSI (2 carriles, hasta 1.5 Gbps por carril) y 1x interfaz DVP paralela (16 bits)",
|
||||
"sdio": "1 controlador host SD/MMC (SDHOST)",
|
||||
"sensor_temperatura": "Sí (1 sensor 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": "USB Serial/JTAG integrado y JTAG externo",
|
||||
"esp_idf_minimo": "ESP-IDF v5.3+",
|
||||
"arduino_core": "En desarrollo (core oficial)",
|
||||
"encapsulamento": "BGA y QFN",
|
||||
"modulos": "ESP32-P4-Function-EV-Board, placas DevKit",
|
||||
"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",
|
||||
"ethernet_mac": "1 (100 Mbps RMII)",
|
||||
"sensor_hall": "No"
|
||||
},
|
||||
"ESP32-H2": {
|
||||
"nome_completo": "ESP32-H2",
|
||||
"icone": "🔋",
|
||||
"descricao": "Enfocado en ultra bajo consumo con Bluetooth 6.0, Zigbee y Thread. Sin soporte para Wi-Fi",
|
||||
"arquitetura": "RISC-V single-core de 32 bits (RV32IMAC)",
|
||||
"nucleos": "1 (Single-core)",
|
||||
"frequencia": "Hasta 96 MHz",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256",
|
||||
"rsa": "Sí (RSA-3072)",
|
||||
"ecc": "Sí (ECC HW)",
|
||||
"ecdsa": "Sí (ECDSA HW)",
|
||||
"hmac": "Sí",
|
||||
"assinatura_digital": "Sí (Digital Signature peripheral)",
|
||||
"key_manager": "No",
|
||||
"rng": "Sí (TRNG por hardware)",
|
||||
"criptografia_flash": "Sí (XTS-AES-128)",
|
||||
"secure_boot": "V2 (RSA-3072 / ECDSA)",
|
||||
"protecao_dpa": "No"
|
||||
},
|
||||
"wifi": "No (sin radio Wi-Fi)",
|
||||
"bluetooth": "Bluetooth 6.0 LE (modo de 2 Mbps, largo alcance y BLE Mesh)",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0 y Thread 1.3)",
|
||||
"matter": "Sí (soporte nativo para Matter sobre Thread)",
|
||||
"memoria_sram": "320 KB",
|
||||
"memoria_sram_rtc": "4 KB LP SRAM",
|
||||
"memoria_rom": "128 KB (para arranque y funciones del núcleo)",
|
||||
"flash_externa": "Hasta 16 MB vía QSPI / 2 MB o 4 MB integrada en SiP",
|
||||
"psram_externa": "No",
|
||||
"gpio": "19",
|
||||
"adc": "1x SAR ADC de 12 bits, hasta 5 canales",
|
||||
"dac": "No",
|
||||
"touch": "No",
|
||||
"uart": "2",
|
||||
"spi": "SPI0/1 para Flash, SPI2 para propósito general",
|
||||
"i2c": "2",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (hasta 6 canales), MCPWM",
|
||||
"usb": "1x USB Serial/JTAG integrado",
|
||||
"sensor_temperatura": "Sí (1 sensor interno)",
|
||||
"consumo_energia": {
|
||||
"active": "24-140 mA (radio, 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": "USB Serial/JTAG integrado o JTAG externo",
|
||||
"esp_idf_minimo": "ESP-IDF v5.1+",
|
||||
"arduino_core": "Sí (core oficial)",
|
||||
"encapsulamento": "QFN32 (5×5 mm)",
|
||||
"modulos": "ESP32-H2-WROOM-07, ESP32-H2-MINI-1 y 3 más",
|
||||
"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",
|
||||
"coprocessador_ulp": "No",
|
||||
"ethernet": "No",
|
||||
"ethernet_mac": "No",
|
||||
"sensor_hall": "No"
|
||||
},
|
||||
"ESP32-H4": {
|
||||
"nome_completo": "ESP32-H4",
|
||||
"icone": "🛡️",
|
||||
"descricao": "SoC dual-core RISC-V de altísima eficiencia energética con Bluetooth 5.4 LE (LE Audio) e IEEE 802.15.4 para Thread, Zigbee y Matter. Sin Wi-Fi",
|
||||
"status_documentacao": "Anunciado por Espressif; soporte para LE Audio y optimización de baja latencia",
|
||||
"arquitetura": "RISC-V dual-core de 32 bits (núcleo de aplicación y núcleo de conectividad/LP)",
|
||||
"nucleos": "2 (Dual-core)",
|
||||
"frequencia": "Hasta 96 MHz",
|
||||
"seguranca": {
|
||||
"aes": "AES-128/256",
|
||||
"sha": "SHA-1/224/256/384/512",
|
||||
"rsa": "Sí (RSA-3072)",
|
||||
"ecc": "Sí (ECC HW)",
|
||||
"ecdsa": "Sí (ECDSA HW)",
|
||||
"hmac": "Sí",
|
||||
"assinatura_digital": "Sí (Digital Signature peripheral)",
|
||||
"key_manager": "Sí (Key Manager integrado)",
|
||||
"rng": "Sí (TRNG por hardware)",
|
||||
"criptografia_flash": "Sí (XTS-AES-128/256)",
|
||||
"secure_boot": "V2 (RSA-3072 / ECDSA)",
|
||||
"protecao_dpa": "Sí (resistencia DPA de hardware)"
|
||||
},
|
||||
"wifi": "No (sin radio Wi-Fi)",
|
||||
"bluetooth": "Bluetooth 5.4 LE (soporte para Bluetooth LE Audio, Auracast, modo de 2 Mbps y largo alcance)",
|
||||
"zigbee_thread": "IEEE 802.15.4 (Zigbee 3.0 y Thread 1.3/1.4)",
|
||||
"matter": "Sí (soporte nativo para Matter sobre Thread con alta eficiencia)",
|
||||
"memoria_sram": "384 KB",
|
||||
"memoria_sram_rtc": "16 KB LP SRAM",
|
||||
"memoria_rom": "256 KB (para arranque y funciones del núcleo)",
|
||||
"flash_externa": "Hasta 16 MB vía QSPI / SiP integrado",
|
||||
"psram_externa": "Soporte para PSRAM en SiP (hasta 2 MB/4 MB)",
|
||||
"gpio": "40",
|
||||
"adc": "1x SAR ADC de 12 bits, hasta 8 canales",
|
||||
"dac": "No",
|
||||
"touch": "No",
|
||||
"uart": "2",
|
||||
"spi": "SPI, QSPI",
|
||||
"i2c": "2",
|
||||
"i2s": "1",
|
||||
"pwm": "LED PWM (hasta 6 canales), MCPWM",
|
||||
"can": "1 (CAN 2.0, TWAI®)",
|
||||
"usb": "1x USB Serial/JTAG integrado",
|
||||
"sensor_temperatura": "Sí (1 sensor interno)",
|
||||
"consumo_energia": {
|
||||
"active": "No divulgado (documentación preliminar)"
|
||||
},
|
||||
"temperatura_operacao": "-40°C a 105°C",
|
||||
"temperatura_armazenamento": "No divulgado (documentación preliminar)",
|
||||
"depuracao": "USB Serial/JTAG integrado o JTAG externo",
|
||||
"esp_idf_minimo": "ESP-IDF v5.4+",
|
||||
"arduino_core": "En desarrollo (core oficial)",
|
||||
"encapsulamento": "QFN32 (4×4 mm) y QFN40 (5×5 mm)",
|
||||
"modulos": "ESP32-H4-WROOM, módulos integrados previstos para 2026",
|
||||
"guia_de_programacao": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32h4/get-started/index.html",
|
||||
"cor": "#e83e8c",
|
||||
"coprocessador_ulp": "Sí (LP core de ultra bajo consumo)",
|
||||
"ethernet": "No",
|
||||
"ethernet_mac": "No",
|
||||
"sensor_hall": "No"
|
||||
}
|
||||
}
|
||||
+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", "es"]).
|
||||
export const ENABLED_LOCALES = ["pt", "en", "es"];
|
||||
|
||||
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");
|
||||
}
|
||||
+3
-2
@@ -1,8 +1,9 @@
|
||||
import { defineRouting } from "next-intl/routing";
|
||||
import { ENABLED_LOCALES } from "./links";
|
||||
|
||||
export const routing = defineRouting({
|
||||
locales: ["pt", "en", "es", "fr", "de", "zh-CN"],
|
||||
defaultLocale: "en",
|
||||
locales: ENABLED_LOCALES,
|
||||
defaultLocale: ENABLED_LOCALES.includes("en") ? "en" : (ENABLED_LOCALES[0] || "pt"),
|
||||
localePrefix: "always",
|
||||
pathnames: {
|
||||
"/": "/",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,700 @@
|
||||
/**
|
||||
* Base de datos estructurada para la guía de diagnóstico, errores comunes y solución de problemas en ESP32.
|
||||
* Cubre 6 categorías técnicas con causas raíz, comparación de buenas prácticas vs soluciones temporales y ejemplos de código
|
||||
* en Arduino C++, ESP-IDF (C) y MicroPython.
|
||||
*/
|
||||
|
||||
export const categoriasDiagnostico = [
|
||||
{
|
||||
id: "alimentacao",
|
||||
nome: "Alimentación y Hardware",
|
||||
icone: "Zap",
|
||||
cor: "amber",
|
||||
descricao: "Caídas de tensión por picos de RF Wi-Fi/BLE, pines de strapping en conflicto, ruido electromagnético y problemas de LDO.",
|
||||
},
|
||||
{
|
||||
id: "cpu-panics",
|
||||
nome: "Pánicos de CPU y Guru Meditation",
|
||||
icone: "Cpu",
|
||||
cor: "red",
|
||||
descricao: "Punteros nulos, violaciones de acceso a memoria (Load/StoreProhibited), instrucciones ilegales y pánicos de caché en ISRs.",
|
||||
},
|
||||
{
|
||||
id: "freertos",
|
||||
nome: "FreeRTOS y Multitarea",
|
||||
icone: "Layers",
|
||||
cor: "purple",
|
||||
descricao: "Task Watchdog (TWDT), Interrupt Watchdog (IWDT), desbordamiento de pila (Stack Overflow) y bloqueos del planificador.",
|
||||
},
|
||||
{
|
||||
id: "memoria",
|
||||
nome: "Memoria, Heap y PSRAM",
|
||||
icone: "Activity",
|
||||
cor: "blue",
|
||||
descricao: "Fragmentación del heap, fugas de memoria (Memory Leaks), asignaciones DMA y restricciones de velocidad en PSRAM.",
|
||||
},
|
||||
{
|
||||
id: "boot-flash",
|
||||
nome: "Bootloader y Grabación",
|
||||
icone: "Terminal",
|
||||
cor: "emerald",
|
||||
descricao: "Fallas de comunicación serie (DTR/RTS), errores de lectura en Flash SPI, discrepancia de reloj y particiones corruptas.",
|
||||
},
|
||||
{
|
||||
id: "conectividade",
|
||||
nome: "Conectividad y Protocolos",
|
||||
icone: "Wifi",
|
||||
cor: "cyan",
|
||||
descricao: "Timeouts de baliza Wi-Fi, fallos de handshake TLS/HTTPS por ausencia de reloj SNTP e inestabilidad de señal.",
|
||||
},
|
||||
];
|
||||
|
||||
export const sintomasRapidos = [
|
||||
{ id: "bootloop", rotulo: "🔄 Bucle de arranque (Crash loop)", categoria: "todos" },
|
||||
{ id: "wifi-crash", rotulo: "📶 Se reinicia al activar Wi-Fi/BLE", categoria: "alimentacao" },
|
||||
{ id: "upload-fail", rotulo: "🔌 Fallo al subir firmware (Error de grabación)", categoria: "boot-flash" },
|
||||
{ id: "random-freeze", rotulo: "⏱️ Se congela tras minutos u horas", categoria: "memoria" },
|
||||
{ id: "null-pointer", rotulo: "💥 Guru Meditation (Crash de CPU)", categoria: "cpu-panics" },
|
||||
{ id: "wdt-reset", rotulo: "🐕 Watchdog activado (Reset por TWDT)", categoria: "freertos" },
|
||||
{ id: "tls-fail", rotulo: "🔒 Fallo en conexión HTTPS / SSL", categoria: "conectividade" },
|
||||
];
|
||||
|
||||
export const errosCatalogo = [
|
||||
{
|
||||
id: "brownout-reset",
|
||||
titulo: "Reinicio por detector de Brownout (Caída de tensión)",
|
||||
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: "La tensión de alimentación del ESP32 cayó por debajo del umbral de seguridad (aproximadamente 2.8V ~ 2.43V).",
|
||||
causaRaiz:
|
||||
"Al inicializar las radios Wi-Fi o BLE, el amplificador de potencia (PA) demanda picos de corriente instantáneos superiores a 500 mA en menos de 1 ms. Si la fuente de alimentación, cables USB largos/delgados, pistas de protoboard o el regulador LDO no pueden suministrar esa corriente transitoria con baja impedancia, el voltaje en el riel de 3.3V colapsa momentáneamente, activando el circuito comparador interno de Brownout para evitar la corrupción de la memoria Flash y estados lógicos indefinidos.",
|
||||
gambiarra: {
|
||||
titulo: "Desactivar el detector de Brownout por software",
|
||||
descricao: "Llamar a WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0) para suprimir el error en el código.",
|
||||
consequencia: "Extremadamente peligroso: el ESP32 continúa ejecutando instrucciones bajo subtensión, corrompiendo la memoria Flash SPI, bloqueando registros periféricos y causando fallos erráticos en campo sin previo aviso.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Dimensionamiento adecuado de hardware y capacitores de desacoplo",
|
||||
passos: [
|
||||
"Añadir un capacitor de tantalio o cerámico de baja ESR de 10 µF a 100 µF en paralelo con un capacitor cerámico de 100 nF lo más cerca posible de los pines 3V3 y GND del ESP32.",
|
||||
"Utilizar reguladores LDO diseñados para picos de al menos 600 mA a 1 A con excelente respuesta transitoria (ej.: AP2112K, ME6211, TPS73733 o XC6206 robusto). Evitar clones deficientes del AMS1117.",
|
||||
"Evitar alimentar el ESP32 a través de pistas largas de protoboard con cables jumper delgados cuando el Wi-Fi transmite a máxima potencia.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// ¡NO desactive el detector de Brownout! Si necesita reducir picos de corriente en pruebas de banco:
|
||||
#include <WiFi.h>
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
// Opcional: Reducir ligeramente la potencia máxima de transmisión Wi-Fi de 20dBm a 17dBm recorta los picos de corriente un ~20%
|
||||
WiFi.setTxPower(WIFI_POWER_17dBm);
|
||||
WiFi.begin("SSID", "PASSWORD");
|
||||
}`,
|
||||
codigoEspIdf: `// Configuración en ESP-IDF:
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
void app_main(void) {
|
||||
// En menuconfig: Component config -> ESP32-specific -> Hardware Brownout Reset (Mantener ACTIVADO)
|
||||
// Para mitigar picos transitorios en diseños con restricciones de energía:
|
||||
esp_wifi_set_max_tx_power(68); // 68 = 17dBm (unidades de 0.25dBm)
|
||||
}`,
|
||||
codigoMicroPython: `# Conexión Wi-Fi segura en MicroPython con estabilización de rieles:
|
||||
import network
|
||||
import time
|
||||
|
||||
wlan = network.WLAN(network.STA_IF)
|
||||
wlan.active(True)
|
||||
|
||||
# Esperar a que se estabilicen los rieles antes de activar el transmisor
|
||||
time.sleep_ms(200)
|
||||
wlan.connect("SSID", "PASSWORD")
|
||||
|
||||
attempts = 0
|
||||
while not wlan.isconnected() and attempts < 30:
|
||||
time.sleep_ms(200)
|
||||
attempts += 1`,
|
||||
},
|
||||
{
|
||||
id: "strapping-pins",
|
||||
titulo: "Conflicto en pines de arranque (Strapping Pins) durante el encendido",
|
||||
categoria: "alimentacao",
|
||||
sintomas: ["bootloop", "upload-fail"],
|
||||
gravidade: "Alta",
|
||||
logSerial: "rst:0x10 (RTCWDT_RTC_RESET),boot:0x3 (DOWNLOAD_BOOT(UART/SPI))\nwaiting for download",
|
||||
resumo: "El ESP32 entra inesperadamente en modo de descarga de firmware o falla al arrancar debido a niveles lógicos forzados en los pines de arranque.",
|
||||
causaRaiz:
|
||||
"Durante el reinicio por hardware, el circuito interno muestrea los niveles lógicos presentes en pines específicos (ej.: GPIO0, GPIO2, GPIO12, GPIO15 en ESP32 clásico; GPIO8, GPIO9 en ESP32-C3/C6). Si hay periféricos externos conectados (sensores I2C, tiras LED, relés) que fuerzan estos pines a niveles altos o bajos en el instante del arranque, el chip interpreta que debe entrar en modo de descarga UART o altera el voltaje interno del LDO de la memoria Flash (GPIO12 en 3.3V vs 1.8V), impidiendo la ejecución del código.",
|
||||
gambiarra: {
|
||||
titulo: "Desconectar los cables manualmente antes de cada encendido",
|
||||
descricao: "Retirar los módulos externos cada vez que se reinicia o programa la placa.",
|
||||
consequencia: "Inviable para cualquier producto en producción o gabinete cerrado, propenso a errores humanos y desgaste de conectores.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Aislamiento de pines de arranque o reasignación a GPIOs seguros",
|
||||
passos: [
|
||||
"Reservar los pines de arranque exclusivamente para funciones internas o dejarlos sin conexiones externas permanentes.",
|
||||
"En ESP32 clásico, evitar usar GPIO0, GPIO2, GPIO12 y GPIO15 para cargas externas que contengan resistencias pull-up o pull-down incorporadas.",
|
||||
"Utilizar transistores de aislamiento (búferes tri-state o conmutadores analógicos controlados por un GPIO libre tras el arranque) si es estrictamente necesario compartir esos pines.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// Mapeo seguro de pines en Arduino para evitar interferir con strapping:
|
||||
// En ESP32 clásico: usar GPIO16, 17, 18, 19, 21, 22, 23 (libres de strapping)
|
||||
const int PIN_RELE = 22; // SEGURO: GPIO22 no es pin de arranque ni tiene restricciones de boot
|
||||
|
||||
void setup() {
|
||||
pinMode(PIN_RELE, OUTPUT);
|
||||
digitalWrite(PIN_RELE, LOW);
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF: Configuración de GPIOs fuera de strapping
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#define SAFE_GPIO_OUTPUT GPIO_NUM_22
|
||||
|
||||
void app_main(void) {
|
||||
gpio_config_t io_conf = {
|
||||
.pin_bit_mask = (1ULL << SAFE_GPIO_OUTPUT),
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_ENABLE,
|
||||
.intr_type = GPIO_INTR_DISABLE
|
||||
};
|
||||
gpio_config(&io_conf);
|
||||
}`,
|
||||
codigoMicroPython: `# MicroPython: Asignación limpia a GPIO seguro
|
||||
from machine import Pin
|
||||
|
||||
# Usar GPIO seguro que no interfiera con el ciclo de arranque
|
||||
pin_rele = Pin(22, Pin.OUT, value=0)`,
|
||||
},
|
||||
{
|
||||
id: "guru-load-prohibited",
|
||||
titulo: "Guru Meditation: LoadProhibited / StoreProhibited (Acceso a puntero nulo)",
|
||||
categoria: "cpu-panics",
|
||||
sintomas: ["null-pointer", "bootloop"],
|
||||
gravidade: "Crítica",
|
||||
logSerial: "Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.\nCore 1 register dump:\nPC : 0x400d1234 PS : 0x00060030 A0 : 0x800d1567 A1 : 0x3ffb1230\nA2 : 0x00000000 A3 : 0x3ffb5000",
|
||||
resumo: "La aplicación intentó leer (LoadProhibited) o escribir (StoreProhibited) en una dirección de memoria protegida o puntero nulo (0x00000000).",
|
||||
causaRaiz:
|
||||
"Ocurre cuando el software desreferencia un puntero no inicializado, un puntero nulo devuelto por una función que falló (como malloc sin memoria suficiente o WiFiClient no conectado), o intenta acceder a una estructura de datos ya liberada (use-after-free). Al observar el volcado de registros, si A2 o A3 contienen 0x00000000 o valores cercanos a cero, se confirma la desreferencia nula.",
|
||||
gambiarra: {
|
||||
titulo: "Reinicio automático sin depuración mediante ESP.restart()",
|
||||
descricao: "Configurar el sistema para reiniciar ante fallos sin investigar la causa raíz del crash.",
|
||||
consequencia: "El error persiste en producción, provocando reinicios cíclicos en campo, pérdida de estado de usuario y posibles corrupciones de archivos.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Validación estricta de punteros y decodificación de la traza de llamadas (Backtrace)",
|
||||
passos: [
|
||||
"Comprobar siempre el retorno de funciones de asignación y conexión (ej.: if (ptr == NULL) return;).",
|
||||
"Utilizar la herramienta ESP Exception Decoder en Arduino IDE o 'idf.py monitor' en ESP-IDF para convertir la dirección del PC (Program Counter) y la traza de llamadas en el archivo y número de línea exactos del código fuente.",
|
||||
"Establecer los punteros a NULL tras invocar free() para evitar dobles liberaciones y accesos a memoria caducada.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// Práctica segura: Comprobación defensiva de punteros
|
||||
void procesarMensaje(const char *mensaje) {
|
||||
if (mensaje == nullptr) {
|
||||
Serial.println(F("[ERROR] Puntero de mensaje nulo recibido. Operación abortada."));
|
||||
return;
|
||||
}
|
||||
// Procesamiento seguro garantizado
|
||||
Serial.printf("Longitud del mensaje: %d\n", strlen(mensaje));
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF: Verificación defensiva y aserciones
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
|
||||
static const char *TAG = "APP_SAFETY";
|
||||
|
||||
esp_err_t inicializar_buffer(char **buf_out, size_t tamano) {
|
||||
ESP_RETURN_ON_FALSE(buf_out != NULL, ESP_ERR_INVALID_ARG, TAG, "Puntero de salida nulo");
|
||||
|
||||
*buf_out = (char *)malloc(tamano);
|
||||
ESP_RETURN_ON_FALSE(*buf_out != NULL, ESP_ERR_NO_MEM, TAG, "Fallo de memoria al asignar buffer");
|
||||
|
||||
return ESP_OK;
|
||||
}`,
|
||||
codigoMicroPython: `# MicroPython maneja excepciones en lugar de pánicos de bajo nivel:
|
||||
def procesar_datos(sensor):
|
||||
if sensor is None:
|
||||
print("[WARN] Objeto sensor no inicializado")
|
||||
return None
|
||||
try:
|
||||
return sensor.read()
|
||||
except Exception as e:
|
||||
print("Error en lectura:", e)
|
||||
return None`,
|
||||
},
|
||||
{
|
||||
id: "guru-iram-cache",
|
||||
titulo: "Fallo de caché e InstructionFetchError en rutinas de interrupción (ISRs)",
|
||||
categoria: "cpu-panics",
|
||||
sintomas: ["null-pointer", "random-freeze"],
|
||||
gravidade: "Crítica",
|
||||
logSerial: "Guru Meditation Error: Core 0 panic'ed (Cache disabled but cached memory region accessed)\nCore 0 register dump:\nPC : 0x40081234 PS : 0x00060034",
|
||||
resumo: "Ocurrió una interrupción (ISR) mientras la memoria Flash SPI estaba ocupada escribiendo o borrando datos con la caché desactivada.",
|
||||
causaRaiz:
|
||||
"Durante operaciones de escritura o borrado en la memoria Flash SPI (ej.: guardado en NVS, LittleFS o actualizaciones OTA), el controlador de hardware desactiva temporalmente la memoria caché de instrucciones. Si se dispara una interrupción por hardware y su rutina de atención (o cualquier función o constante de cadena a la que llame) reside en la memoria Flash en lugar de la memoria RAM interna (IRAM), la CPU no puede leer la siguiente instrucción y genera un pánico inmediato.",
|
||||
gambiarra: {
|
||||
titulo: "Desactivar interrupciones durante toda la escritura en Flash",
|
||||
descricao: "Bloquear globalmente las interrupciones durante períodos prolongados de escritura.",
|
||||
consequencia: "Genera desbordamientos en búferes de UART, pérdida de paquetes de red Wi-Fi y dispara el Interrupt Watchdog (IWDT).",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Colocar la ISR y sus datos en memoria IRAM y DRAM usando atributos",
|
||||
passos: [
|
||||
"Declarar todas las funciones de interrupción con el atributo IRAM_ATTR (en Arduino/ESP-IDF).",
|
||||
"Evitar llamar a funciones que residan en Flash (como Serial.print, sprintf, malloc o FreeRTOS API estándar sin sufijo FromISR) dentro de la ISR.",
|
||||
"Almacenar constantes accedidas por la ISR con DRAM_ATTR si están fuera de la pila local.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// Rutina de interrupción correcta con IRAM_ATTR:
|
||||
volatile uint32_t contadorPulsos = 0;
|
||||
|
||||
void IRAM_ATTR manejarInterrupcion() {
|
||||
// Prohibido usar Serial.print() aquí adentro (reside en Flash)
|
||||
contadorPulsos++;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
pinMode(4, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(4), manejarInterrupcion, FALLING);
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF: Rutina ISR segura en IRAM
|
||||
#include "esp_attr.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
static volatile uint32_t pulsos = 0;
|
||||
|
||||
static void IRAM_ATTR gpio_isr_handler(void* arg) {
|
||||
pulsos++;
|
||||
// Usar únicamente APIs de FreeRTOS terminadas en FromISR
|
||||
}
|
||||
|
||||
void app_main(void) {
|
||||
gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
|
||||
gpio_isr_handler_add(GPIO_NUM_4, gpio_isr_handler, NULL);
|
||||
}`,
|
||||
codigoMicroPython: `# MicroPython: Reservar memoria para excepciones en interrupciones
|
||||
import micropython
|
||||
from machine import Pin
|
||||
|
||||
micropython.alloc_emergency_exception_buf(100)
|
||||
|
||||
contador = 0
|
||||
def handler(p):
|
||||
global contador
|
||||
contador += 1 # Operaciones atómicas y simples únicamente
|
||||
|
||||
pin = Pin(4, Pin.IN, Pin.PULL_UP)
|
||||
pin.irq(trigger=Pin.IRQ_FALLING, handler=handler)`,
|
||||
},
|
||||
{
|
||||
id: "freertos-twdt",
|
||||
titulo: "Reinicio por Task Watchdog Timer (TWDT Timeout en Core 0 o Core 1)",
|
||||
categoria: "freertos",
|
||||
sintomas: ["wdt-reset", "bootloop"],
|
||||
gravidade: "Alta",
|
||||
logSerial: "E (10543) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:\nE (10543) task_wdt: - loopTask (CPU 1)\nE (10543) task_wdt: Tasks currently running on other CPUs:\nE (10543) task_wdt: - IDLE0 (CPU 0)",
|
||||
resumo: "Una tarea de FreeRTOS acaparó la CPU de forma continua durante más de 5 segundos sin ceder tiempo a otras tareas.",
|
||||
causaRaiz:
|
||||
"El planificador de FreeRTOS requiere que las tareas de baja prioridad o la tarea IDLE del sistema se ejecuten periódicamente para alimentar el perro guardián (Watchdog). Si un bucle 'while(1)' o 'for' ejecuta cálculos intensivos o espera una condición sin llamar a vTaskDelay o ceder el procesador (yield), el temporizador del TWDT expira y reinicia el SoC para evitar congelamientos completos.",
|
||||
gambiarra: {
|
||||
titulo: "Aumentar el tiempo del Watchdog a 60 segundos o desactivarlo",
|
||||
descricao: "Elevar el umbral en menuconfig para ocultar el bloqueo de la tarea.",
|
||||
consequencia: "Si el código se congela realmente en campo, el sistema tardará minutos en recuperarse o quedará bloqueado indefinidamente consumiendo batería.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Introducir cesión explícita de CPU (vTaskDelay) o arquitectura dirigida por eventos",
|
||||
passos: [
|
||||
"Añadir al menos 'vTaskDelay(pdMS_TO_TICKS(1))' o 'delay(1)' dentro de cualquier bucle de procesamiento continuo.",
|
||||
"Sustituir bucles de espera activa (polling continuo) por colas de FreeRTOS (xQueueReceive) o semáforos binarios bloqueantes.",
|
||||
"Alimentar manualmente el perro guardián con esp_task_wdt_reset() si se realizan tareas largas inevitables.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// Prevención del TWDT en Arduino:
|
||||
void loop() {
|
||||
// Procesamiento pesado:
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
// Procesar elemento...
|
||||
|
||||
// Ceder CPU a la tarea IDLE cada cierto intervalo:
|
||||
if (i % 500 == 0) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1)); // O delay(1); alimenta el Watchdog
|
||||
}
|
||||
}
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF: Tarea bloqueante basada en colas (0% consumo de CPU en reposo)
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
static QueueHandle_t colaEventos;
|
||||
|
||||
void tarea_procesadora(void *pvParameters) {
|
||||
int evento;
|
||||
while (1) {
|
||||
// Bloquea indefinidamente hasta recibir datos, cediendo el 100% de la CPU:
|
||||
if (xQueueReceive(colaEventos, &evento, portMAX_DELAY) == pdTRUE) {
|
||||
// Procesar evento de forma segura
|
||||
}
|
||||
}
|
||||
}`,
|
||||
codigoMicroPython: `# MicroPython: Uso de asyncio para evitar bloqueos
|
||||
import uasyncio as asyncio
|
||||
|
||||
async def tarea_pesada():
|
||||
while True:
|
||||
# Ejecutar lógica
|
||||
await asyncio.sleep_ms(10) # Cede el bucle de eventos cooperativo`,
|
||||
},
|
||||
{
|
||||
id: "freertos-stack-overflow",
|
||||
titulo: "Desbordamiento de pila en tarea FreeRTOS (Stack Overflow)",
|
||||
categoria: "freertos",
|
||||
sintomas: ["bootloop", "random-freeze"],
|
||||
gravidade: "Crítica",
|
||||
logSerial: "***ERROR*** A stack overflow in task MiTarea has been detected.\nBacktrace:0x4008b123:0x3ffb7890 0x4008c456:0x3ffb78b0",
|
||||
resumo: "La tarea excedió el espacio de memoria de pila (stack) asignado en su creación, sobrescribiendo variables de otras tareas.",
|
||||
causaRaiz:
|
||||
"Cada tarea de FreeRTOS recibe un bloque fijo de memoria para su pila local. Declarar arreglos o búferes grandes dentro de funciones locales (ej.: char buffer[2048]), anidar llamadas a funciones con múltiples niveles de recursión o invocar bibliotecas pesadas de JSON/TLS puede consumir rápidamente el espacio asignado, rompiendo el centinela (canary) de seguridad al final de la pila.",
|
||||
gambiarra: {
|
||||
titulo: "Asignar 32 KB de pila a todas las tareas indiscriminadamente",
|
||||
descricao: "Colocar valores gigantescos en el parámetro usStackDepth de cada xTaskCreate.",
|
||||
consequencia: "Agotamiento prematuro de la memoria SRAM interna, imposibilitando inicializar conexiones Wi-Fi o crear nuevas tareas.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Medir el margen de pila con uxTaskGetStackHighWaterMark y alojar búferes en el heap",
|
||||
passos: [
|
||||
"Monitorizar periódicamente el remanente mínimo de pila mediante uxTaskGetStackHighWaterMark(NULL).",
|
||||
"Trasladar arreglos de más de 256 bytes fuera de la pila local, asignándolos dinámicamente en el heap (malloc) o de forma estática.",
|
||||
"Dimensionar la pila de tareas que utilicen TLS/HTTPS con un mínimo de 6 KB a 8 KB.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// Comprobación de pila remanente en Arduino:
|
||||
void tareaMonitoreada(void *pvParameters) {
|
||||
while (1) {
|
||||
// Lógica de trabajo...
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
// Devuelve el número mínimo de bytes libres que le quedaron a la pila:
|
||||
UBaseType_t remanente = uxTaskGetStackHighWaterMark(NULL);
|
||||
Serial.printf("Margen de seguridad de pila: %d bytes libres\n", remanente);
|
||||
}
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF: Creación con dimensionamiento y habilitación de verificación de pila
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
// En menuconfig: Component config -> FreeRTOS -> Enable Stack Overflow Detection (Method 2)
|
||||
|
||||
void tarea_optimizada(void *pvParameters) {
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
UBaseType_t espacioLibre = uxTaskGetStackHighWaterMark(NULL);
|
||||
// Si espacioLibre < 512 bytes, aumente el stack en xTaskCreate
|
||||
}
|
||||
}`,
|
||||
codigoMicroPython: `# MicroPython: Consulta de estado de memoria
|
||||
import gc
|
||||
|
||||
gc.collect()
|
||||
print("Memoria libre en RAM:", gc.mem_free(), "bytes")`,
|
||||
},
|
||||
{
|
||||
id: "memoria-fragmentacao-heap",
|
||||
titulo: "Fragmentación del heap y fugas de memoria (Memory Leaks)",
|
||||
categoria: "memoria",
|
||||
sintomas: ["random-freeze", "wifi-crash"],
|
||||
gravidade: "Alta",
|
||||
logSerial: "E (45210) esp_netif_lwip: Failed to allocate netif buffer\nE (45210) wifi: malloc 1420 failed, free heap: 42300, max allocable: 1200",
|
||||
resumo: "El sistema tiene memoria libre total, pero no puede asignar un bloque contiguo por estar fragmentado en fragmentos pequeños.",
|
||||
causaRaiz:
|
||||
"El uso recurrente de la clase 'String' en bucles rápidos en Arduino, la manipulación de cadenas grandes mediante concatenación (+), o llamadas a malloc sin su correspondiente free van partiendo la memoria dinámica en islas minúsculas. Cuando el driver de Wi-Fi o TLS solicita un búfer de 2 a 4 KB contiguos para recibir un paquete de red, la asignación falla a pesar de que el informe global indique decenas de kilobytes libres.",
|
||||
gambiarra: {
|
||||
titulo: "Reiniciar el microcontrolador preventivamente cada noche",
|
||||
descricao: "Configurar un temporizador para forzar ESP.restart() a intervalos regulares.",
|
||||
consequencia: "Interrupción de operaciones activas, pérdida de estados de conexión y desatención de la causa subyacente.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Uso de búferes estáticos, reserva de memoria previa y monitorización del bloque máximo asignable",
|
||||
passos: [
|
||||
"Sustituir objetos String dinámicos por arreglos de caracteres tradicionales (char buffer[128]) con snprintf.",
|
||||
"Si utiliza la clase String de Arduino, invocar 'str.reserve(tamañoMaximo)' de forma temprana para evitar continuas reasignaciones en el heap.",
|
||||
"Supervisar el estado con heap_caps_get_largest_free_block(MALLOC_CAP_8BIT) en lugar de consultar únicamente el heap total.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// Práctica recomendada en Arduino: Uso de snprintf y búfer fijo
|
||||
void formatearDatos(float temp, float hum) {
|
||||
char jsonBuffer[64];
|
||||
// Seguro, rápido y no produce fragmentación en el heap:
|
||||
snprintf(jsonBuffer, sizeof(jsonBuffer), "{\"t\":%.2f,\"h\":%.2f}", temp, hum);
|
||||
Serial.println(jsonBuffer);
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF: Inspección del bloque contiguo más grande
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
void verificar_salud_memoria(void) {
|
||||
size_t totalLibre = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
size_t mayorBloque = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
|
||||
|
||||
ESP_LOGI("HEAP", "Total libre: %d bytes | Mayor bloque contiguo: %d bytes",
|
||||
totalLibre, mayorBloque);
|
||||
// Si mayorBloque es significativamente menor que totalLibre, existe fragmentación severa
|
||||
}`,
|
||||
codigoMicroPython: `# MicroPython: Recolección proactiva de basura
|
||||
import gc
|
||||
|
||||
def ciclo_mantenimiento():
|
||||
# Forzar compactación y recolección de basura antes de asignaciones grandes:
|
||||
gc.collect()
|
||||
print("Memoria disponible tras GC:", gc.mem_free())`,
|
||||
},
|
||||
{
|
||||
id: "memoria-dma-psram",
|
||||
titulo: "Fallo en asignaciones DMA con memoria externa (PSRAM)",
|
||||
categoria: "memoria",
|
||||
sintomas: ["null-pointer", "random-freeze"],
|
||||
gravidade: "Alta",
|
||||
logSerial: "E (1234) spi_master: spi_bus_add_device(345): buffer not in DMA-capable memory\nE (1234) lcd: esp_lcd_panel_draw_bitmap failed (-1)",
|
||||
resumo: "Un controlador periférico (SPI, I2S, LCD) intentó transferir datos por DMA directamente desde o hacia una dirección de memoria PSRAM externa no compatible.",
|
||||
causaRaiz:
|
||||
"Los periféricos de alta velocidad utilizan controladores DMA que transfieren datos entre memorias y líneas de hardware de forma autónoma. En chips clásicos (como ESP32 y ESP32-S2), el motor DMA carece de acceso físico directo al bus SPI externo de la PSRAM. Intentar pasar un búfer alojado en PSRAM a funciones de dibujo LCD o transferencias SPI DMA produce un fallo inmediato de asignación.",
|
||||
gambiarra: {
|
||||
titulo: "Desactivar transferencias DMA y operar en modo polling por CPU",
|
||||
descricao: "Configurar los buses para transferir byte por byte mediante registros directos.",
|
||||
consequencia: "Caída catastrófica del rendimiento gráfico (de 30 FPS a menos de 5 FPS en pantallas a color) y uso total de la CPU.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Asignar búferes DMA en memoria interna SRAM con capacidades MALLOC_CAP_DMA",
|
||||
passos: [
|
||||
"Alojar siempre los descriptores y búferes activos de DMA en la memoria SRAM interna usando 'heap_caps_malloc(tamaño, MALLOC_CAP_DMA)'.",
|
||||
"Utilizar arquitecturas de doble búfer (ping-pong): mantener los recursos gráficos en PSRAM y copiar por bloques pequeños a un búfer interno DMA de SRAM antes del envío.",
|
||||
"En ESP32-S3 y ESP32-P4, verificar las versiones de revisión de silicio que admiten transferencias EDMA directas desde PSRAM.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// Asignación segura de memoria compatible con DMA en Arduino:
|
||||
#include <esp_heap_caps.h>
|
||||
|
||||
uint8_t *bufferDma = nullptr;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
// Asignar exclusivamente en memoria interna con capacidad DMA:
|
||||
bufferDma = (uint8_t *)heap_caps_malloc(4096, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
if (bufferDma == nullptr) {
|
||||
Serial.println(F("[ERROR] Memoria SRAM interna insuficiente para DMA"));
|
||||
}
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF: Asignación de búfer para transacciones de bus SPI
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
uint8_t* asignar_buffer_spi(size_t len) {
|
||||
return (uint8_t*)heap_caps_aligned_alloc(32, len, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
|
||||
}`,
|
||||
codigoMicroPython: `# MicroPython: Asignación de búfer con alineación para periféricos
|
||||
import uctypes
|
||||
|
||||
# MicroPython gestiona la memoria DMA internamente al inicializar SPI o Display con drivers compilados`,
|
||||
},
|
||||
{
|
||||
id: "boot-failed-connect",
|
||||
titulo: "Failed to connect to ESP32: Timed out waiting for packet header (Fallo de conexión en subida)",
|
||||
categoria: "boot-flash",
|
||||
sintomas: ["upload-fail"],
|
||||
gravidade: "Media",
|
||||
logSerial: "Connecting........_____....._____....._____\nA fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header",
|
||||
resumo: "La herramienta esptool en la computadora host no pudo comunicarse con la ROM de arranque del ESP32 a través del puerto serie.",
|
||||
causaRaiz:
|
||||
"El circuito de reinicio automático formado por transistores y líneas DTR/RTS en la placa de desarrollo no logró colocar a tiempo el pin GPIO0 en nivel bajo en el instante en que el pin EN pasó de bajo a alto. Causas muy frecuentes incluyen: cables USB de solo carga (sin líneas de datos D+/D-), ausencia de capacitor de retardo entre EN y GND, o puertos serie bloqueados por otros programas de terminal abiertos en la computadora.",
|
||||
gambiarra: {
|
||||
titulo: "Mantener pulsado manualmente el botón BOOT en cada grabación",
|
||||
descricao: "Presionar con el dedo el botón físico de BOOT de la placa hasta que el esptool detecte el chip.",
|
||||
consequencia: "Tedioso durante sesiones prolongadas de desarrollo e inviable cuando el microcontrolador se ubica en un gabinete sellado o en un rack.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Capacitor de 10 µF entre EN y GND y cable USB de datos de calidad",
|
||||
passos: [
|
||||
"Soldar o conectar un capacitor cerámico o electrolítico de 1 µF a 10 µF entre el pin EN (CHIP_PU) y el pin GND de la placa DevKit para generar el retardo RC necesario.",
|
||||
"Asegurarse de cerrar cualquier monitor serie o software de depuración antes de iniciar el proceso de subida.",
|
||||
"Verificar con un polímetro la continuidad de las líneas D+ y D- del cable USB.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// No requiere código fuente en firmware: Este problema radica en la etapa de hardware y conexión serie.
|
||||
// Para placas basadas en ESP32-S3 o C3 con USB Serial/JTAG nativo:
|
||||
// En el menú Tools de Arduino IDE:
|
||||
// USB CDC On Boot: "Enabled"
|
||||
// Upload Mode: "UART0 / Hardware CDC"`,
|
||||
codigoEspIdf: `// Verificación rápida desde la consola de terminal con esptool:
|
||||
// idf.py -p /dev/ttyUSB0 flash monitor
|
||||
// Si falla, reducir la velocidad de baudios en el comando:
|
||||
// esptool.py -p /dev/ttyUSB0 -b 115200 chip_id`,
|
||||
codigoMicroPython: `# En caso de error de conexión al flashear el firmware binario de MicroPython:
|
||||
# esptool.py --port /dev/ttyUSB0 --baud 115200 erase_flash
|
||||
# esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 esp32-firmware.bin`,
|
||||
},
|
||||
{
|
||||
id: "tls-sntp-clock-fail",
|
||||
titulo: "Fallo en handshake TLS/HTTPS por reloj desincronizado (Año 1970)",
|
||||
categoria: "conectividade",
|
||||
sintomas: ["tls-fail"],
|
||||
gravidade: "Alta",
|
||||
logSerial: "E (5210) esp-tls-mbedtls: mbedtls_ssl_handshake returned -0x2700\nE (5210) esp-tls: Failed to verify peer certificate! (0x00000008 - BADCERT_EXPIRED / NOT_YET_VALID)",
|
||||
resumo: "Las solicitudes HTTPS, MQTTS o WebSockets seguros fallan al verificar el certificado de seguridad del servidor.",
|
||||
causaRaiz:
|
||||
"Al encenderse, el reloj de tiempo real (RTC) interno del ESP32 se inicializa en la época Unix estándar (01 de enero de 1970). Los certificados digitales SSL/TLS emitidos por autoridades certificadoras (como Let's Encrypt o DigiCert) definen un período de validez temporal estricto (ej.: válido de 2024 a 2026). Al comprobar la fecha del certificado con su reloj fijado en 1970, la pila MbedTLS rechaza la conexión con el error BADCERT_NOT_YET_VALID.",
|
||||
gambiarra: {
|
||||
titulo: "Desactivar la verificación de certificados con setInsecure()",
|
||||
descricao: "Configurar el cliente TLS para aceptar cualquier certificado sin validación.",
|
||||
consequencia: "Grave vulnerabilidad de seguridad: deja al dispositivo expuesto a ataques Man-in-the-Middle (MitM), donde un atacante en la red local puede interceptar credenciales y datos privados.",
|
||||
},
|
||||
solucaoEngenharia: {
|
||||
titulo: "Sincronizar la hora vía protocolo SNTP antes de iniciar conexiones seguras",
|
||||
passos: [
|
||||
"Iniciar el cliente SNTP inmediatamente después de que el ESP32 obtenga dirección IP de la red Wi-Fi.",
|
||||
"Esperar a que la hora del sistema sea posterior al año 2024 antes de instanciar clientes HTTP/MQTT seguros.",
|
||||
"Cargar los certificados de las Autoridades Certificadoras raíz (Root CA) de confianza en formato PEM.",
|
||||
],
|
||||
},
|
||||
codigoArduino: `// Sincronización horaria previa obligatoria antes de peticiones HTTPS:
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <time.h>
|
||||
|
||||
void sincronizarHora() {
|
||||
// Servidores NTP estándar globales:
|
||||
configTime(0, 0, "pool.ntp.org", "time.google.com");
|
||||
|
||||
Serial.print("Sincronizando reloj con servidores NTP");
|
||||
time_t ahora = time(nullptr);
|
||||
while (ahora < 1704067200) { // Umbral: 01 de enero de 2024
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
ahora = time(nullptr);
|
||||
}
|
||||
Serial.println("\nHora sincronizada correctamente. HTTPS listo.");
|
||||
}`,
|
||||
codigoEspIdf: `// ESP-IDF: Sincronización horaria mediante SNTP nativo
|
||||
#include "esp_sntp.h"
|
||||
#include "esp_log.h"
|
||||
#include <time.h>
|
||||
|
||||
void inicializar_sntp(void) {
|
||||
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||||
esp_sntp_setservername(0, "pool.ntp.org");
|
||||
esp_sntp_init();
|
||||
|
||||
time_t now = 0;
|
||||
struct tm timeinfo = { 0 };
|
||||
int reintentos = 0;
|
||||
while (timeinfo.tm_year < (2024 - 1900) && ++reintentos < 20) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
time(&now);
|
||||
localtime_r(&now, &timeinfo);
|
||||
}
|
||||
}`,
|
||||
codigoMicroPython: `# MicroPython: Ajuste de reloj mediante ntptime
|
||||
import network
|
||||
import ntptime
|
||||
import time
|
||||
|
||||
wlan = network.WLAN(network.STA_IF)
|
||||
if wlan.isconnected():
|
||||
try:
|
||||
ntptime.settime() # Sincroniza el RTC interno con servidores NTP
|
||||
print("Hora actual sincronizada:", time.localtime())
|
||||
except Exception as e:
|
||||
print("Fallo de sincronización NTP:", e)`,
|
||||
},
|
||||
];
|
||||
|
||||
export const ERROS_COMUNS = errosCatalogo;
|
||||
|
||||
export const analisarLogSerial = [
|
||||
{
|
||||
padrao: /Brownout detector was triggered/i,
|
||||
titulo: "Reinicio por subtensión (Brownout)",
|
||||
tipo: "Alimentación / Hardware",
|
||||
explicacao:
|
||||
"La tensión en el riel de 3.3V cayó por debajo del límite operativo seguro durante picos de corriente del módem RF.",
|
||||
acaoRecomendada:
|
||||
"Añada un capacitor de desacoplo de 10 µF a 100 µF entre 3V3 y GND, o sustituya el cable USB y la fuente de alimentación.",
|
||||
},
|
||||
{
|
||||
padrao: /Guru Meditation Error.*LoadProhibited/i,
|
||||
titulo: "Pánico de CPU: LoadProhibited",
|
||||
tipo: "Software / Puntero Nulo",
|
||||
explicacao:
|
||||
"El código intentó leer una dirección de memoria inválida o puntero desreferenciado con valor NULL.",
|
||||
acaoRecomendada:
|
||||
"Compruebe siempre los punteros antes de acceder a sus miembros y utilice el decodificador de excepciones para localizar la línea.",
|
||||
},
|
||||
{
|
||||
padrao: /Guru Meditation Error.*StoreProhibited/i,
|
||||
titulo: "Pánico de CPU: StoreProhibited",
|
||||
tipo: "Software / Escritura Inválida",
|
||||
explicacao:
|
||||
"El código intentó escribir en una dirección de memoria de solo lectura o en un puntero nulo.",
|
||||
acaoRecomendada:
|
||||
"Verifique las operaciones de escritura en cadenas de texto constantes y la asignación válida de búferes.",
|
||||
},
|
||||
{
|
||||
padrao: /Cache disabled but cached memory region accessed/i,
|
||||
titulo: "Fallo de caché en interrupción (ISR)",
|
||||
tipo: "Software / Flash & RAM",
|
||||
explicacao:
|
||||
"Una rutina de interrupción intentó ejecutar código alojado en Flash mientras la memoria caché estaba deshabilitada por escritura.",
|
||||
acaoRecomendada:
|
||||
"Declare la rutina de interrupción con la macro IRAM_ATTR y no invoque funciones que residan en Flash dentro de la ISR.",
|
||||
},
|
||||
{
|
||||
padrao: /Task watchdog got triggered/i,
|
||||
titulo: "Timeout del Task Watchdog (TWDT)",
|
||||
tipo: "FreeRTOS / Bloqueo de CPU",
|
||||
explicacao:
|
||||
"Una tarea ejecutó un bucle sin ceder tiempo al planificador del sistema durante más de 5 segundos.",
|
||||
acaoRecomendada:
|
||||
"Añada vTaskDelay(1) dentro de los bucles intensivos para permitir que la tarea IDLE alimente el perro guardián.",
|
||||
},
|
||||
{
|
||||
padrao: /A stack overflow in task/i,
|
||||
titulo: "Desbordamiento de pila (Stack Overflow)",
|
||||
tipo: "FreeRTOS / Memoria de Tarea",
|
||||
explicacao:
|
||||
"La tarea agotó el espacio de pila asignado en su creación, corrompiendo el centinela de seguridad.",
|
||||
acaoRecomendada:
|
||||
"Incremente el tamaño de pila en xTaskCreate (ej.: de 2048 a 4096 bytes) y traslade arreglos grandes al heap.",
|
||||
},
|
||||
{
|
||||
padrao: /Timed out waiting for packet header|Failed to connect to ESP32/i,
|
||||
titulo: "Fallo de conexión serie en subida de firmware",
|
||||
tipo: "Bootloader / Conexión",
|
||||
explicacao:
|
||||
"La computadora host no logró colocar el ESP32 en modo de descarga de firmware vía líneas DTR/RTS.",
|
||||
acaoRecomendada:
|
||||
"Conecte un capacitor de 10 µF entre EN y GND, verifique que el cable USB tenga líneas de datos o mantenga presionado el botón BOOT.",
|
||||
},
|
||||
{
|
||||
padrao: /The certificate is not yet valid|-0x2700/i,
|
||||
titulo: "Fallo de certificado SSL/TLS (Reloj en 1970)",
|
||||
tipo: "Conectividad / TLS",
|
||||
explicacao:
|
||||
"El ESP32 intentó validar un certificado HTTPS/TLS con su reloj interno desincronizado en la época de 1970.",
|
||||
acaoRecomendada:
|
||||
"Sincronice la hora mediante el protocolo SNTP (configTime en Arduino o ntptime en MicroPython) antes de iniciar peticiones TLS.",
|
||||
},
|
||||
{
|
||||
padrao: /rst:0x1 \(POWERON_RESET\),boot:0x[0-9a-fA-F]+/i,
|
||||
titulo: "Reinicio por encendido / Muestreo de Strapping Pins",
|
||||
tipo: "Hardware / Boot",
|
||||
explicacao:
|
||||
"El microcontrolador se reinició y registró sus pines de arranque. Si se congela de inmediato, un pin de strapping tiene un nivel incorrecto.",
|
||||
acaoRecomendada:
|
||||
"Compruebe que los pines de arranque GPIOs no estén forzados a niveles incompatibles por circuitos externos en el instante del arranque.",
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,408 @@
|
||||
/**
|
||||
* Base de datos estructurada y completa de términos técnicos del Glosario ESP32 en español.
|
||||
* Abarca todas las series de chips de Espressif (ESP32, S2, S3, S31, C2, C3, C5, C6, C61, H2, H4, P4)
|
||||
* y sus funciones de hardware, periféricos, radio, seguridad y software.
|
||||
*/
|
||||
|
||||
export const categoriasGlossario = [
|
||||
{
|
||||
"id": "processamento",
|
||||
"nome": "Procesamiento, CPU y Silicio",
|
||||
"icone": "Cpu",
|
||||
"emoji": "🧠",
|
||||
"cor": "blue",
|
||||
"descricao": "Arquitecturas Xtensa y RISC-V, núcleos, coprocesadores ULP, aceleradores vectoriales de IA y unidades de punto flotante.",
|
||||
"termos": [
|
||||
{
|
||||
"termo": "Arquitectura Xtensa vs RISC-V",
|
||||
"definicao": "Conjunto de instrucciones base del procesador. El ESP32 clásico, S2 y S3 utilizan núcleos propietarios Tensilica Xtensa (LX6/LX7). Las series modernas C (C2, C3, C5, C6, C61), H (H2, H4) y P (P4) adoptan la arquitectura abierta, modular y eficiente RISC-V (32 bits).",
|
||||
"exemplo": "El ESP32-S3 usa Xtensa LX7 dual-core, mientras que el ESP32-C6 usa RISC-V single-core y el ESP32-P4 usa RISC-V dual-core a 400 MHz."
|
||||
},
|
||||
{
|
||||
"termo": "Núcleos de CPU (Dual-Core vs Single-Core)",
|
||||
"definicao": "Unidades centrales de procesamiento independientes. Los chips dual-core permiten dedicar un núcleo (Core 0) exclusivamente a la radio Wi-Fi/Bluetooth y a la planificación de FreeRTOS, dejando el segundo núcleo (Core 1) 100% libre para la aplicación y cálculos del usuario.",
|
||||
"exemplo": "ESP32, ESP32-S3 y ESP32-P4 son dual-core; ESP32-S2, C2, C3, C6 y H2 son single-core."
|
||||
},
|
||||
{
|
||||
"termo": "Frecuencia de reloj (MHz)",
|
||||
"definicao": "Velocidad de procesamiento medida en Megahertz (MHz). El ESP-IDF ajusta dinámicamente la frecuencia (Dynamic Frequency Scaling - DFS) para ahorrar energía en momentos de inactividad.",
|
||||
"exemplo": "El ESP32-C2 opera hasta 120 MHz; ESP32, S2, S3 y C6 alcanzan 160/240 MHz; y el ESP32-P4 alcanza 400 MHz."
|
||||
},
|
||||
{
|
||||
"termo": "ULP (Coprocesador de ultra bajo consumo)",
|
||||
"definicao": "Procesador secundario independiente de ultra bajo consumo que continúa ejecutando instrucciones, leyendo sensores analógicos (ADC), I2C y pines GPIO mientras los núcleos principales permanecen apagados en Deep Sleep.",
|
||||
"exemplo": "El ESP32 original cuenta con ULP FSM; ESP32-S2, S3 y C6 disponen de ULP RISC-V programable en C; ESP32-P4 cuenta con ULP dedicado de bajo consumo."
|
||||
},
|
||||
{
|
||||
"termo": "Extensiones vectoriales de IA (Vector Extension / ESP-NN)",
|
||||
"definicao": "Instrucciones especializadas de silicio que ejecutan operaciones matemáticas vectoriales y matriciales con enteros (int8/int16) en paralelo, acelerando redes neuronales convolucionales (CNNs) y procesamiento de señales.",
|
||||
"exemplo": "ESP32-S3 y ESP32-P4 aceleran inferencias de reconocimiento facial, detección de voz y modelos TensorFlow Lite for Microcontrollers."
|
||||
},
|
||||
{
|
||||
"termo": "FPU (Unidad de punto flotante)",
|
||||
"definicao": "Unidad de procesamiento de punto flotante por hardware que realiza sumas, multiplicaciones y divisiones con números decimales (`float`) en un único ciclo de reloj, sin sobrecarga por emulación de software.",
|
||||
"exemplo": "Presente en los núcleos Xtensa del ESP32 y ESP32-S3, y en los núcleos RISC-V de alto rendimiento del ESP32-P4."
|
||||
},
|
||||
{
|
||||
"termo": "PPA (Pixel Processing Accelerator)",
|
||||
"definicao": "Acelerador gráfico 2D por hardware exclusivo del ESP32-P4 para manipulación acelerada de imágenes: rotación de fotogramas, escalado (scaling), mezcla alfa (alpha blending) y conversión de espacios de color (RGB565, ARGB8888, YUV420).",
|
||||
"exemplo": "Renderizado de interfaces gráficas complejas (LVGL) a 60 FPS sin sobrecargar los núcleos de CPU principales."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "seguranca",
|
||||
"nome": "Seguridad, Criptografía y eFuses",
|
||||
"icone": "ShieldCheck",
|
||||
"emoji": "🔒",
|
||||
"cor": "red",
|
||||
"descricao": "eFuses inviolables, Secure Boot V2, cifrado de flash XTS-AES, Key Manager, ECC y protección contra DPA.",
|
||||
"termos": [
|
||||
{
|
||||
"termo": "eFuse (Fusibles electrónicos)",
|
||||
"definicao": "Conjunto de fusibles microscópicos de silicio de grabación única e irreversible (One-Time Programmable - OTP). Almacenan claves secretas de cifrado, la dirección MAC de fábrica y bloquean interfaces de depuración en productos comerciales.",
|
||||
"exemplo": "Utilizado con la herramienta `espefuse.py` para grabar claves de Secure Boot y desactivar puertos JTAG antes del envío al usuario final."
|
||||
},
|
||||
{
|
||||
"termo": "Secure Boot (V1 y V2)",
|
||||
"definicao": "Protocolo de arranque seguro en el que el código de la ROM verifica criptográficamente la firma RSA-3072 o ECDSA del bootloader y del firmware antes de permitir su ejecución, impidiendo la inyección de código manipulado.",
|
||||
"exemplo": "ESP32 clásico usa Secure Boot V1; del ESP32-S2 en adelante todos adoptan Secure Boot V2 con múltiples claves de firma."
|
||||
},
|
||||
{
|
||||
"termo": "Cifrado de flash (Flash Encryption)",
|
||||
"definicao": "Mecanismo de hardware que cifra y descifra en tiempo real el contenido de la memoria Flash SPI externa utilizando el algoritmo XTS-AES. Impide la lectura física del firmware en caso de robo de la placa o desoldado del chip de memoria.",
|
||||
"exemplo": "XTS-AES-128 en la mayoría de los chips; ESP32-S3, C5, P4 y H4 también admiten XTS-AES-256."
|
||||
},
|
||||
{
|
||||
"termo": "Key Manager",
|
||||
"definicao": "Módulo de seguridad avanzada que aprovisiona, almacena y opera claves criptográficas en silicio sin exponerlas jamás a la memoria SRAM o al firmware, impidiendo la extracción de claves incluso ante vulnerabilidades de software.",
|
||||
"exemplo": "Presente en series de alta seguridad como ESP32-S31, ESP32-C5 y ESP32-P4."
|
||||
},
|
||||
{
|
||||
"termo": "ECC y ECDSA en hardware",
|
||||
"definicao": "Aceleradores de curvas elípticas (como P-256 y P-384) y algoritmos de firma digital ECDSA en silicio, fundamentales para una conexión rápida y segura a la nube y para los requisitos de atestación del estándar Matter.",
|
||||
"exemplo": "ESP32-S31, C5, C61, P4, H2 y H4 disponen de acelerador de hardware para ECDSA."
|
||||
},
|
||||
{
|
||||
"termo": "HMAC y Firma Digital (DS)",
|
||||
"definicao": "Periféricos de autenticación criptográfica que calculan códigos HMAC y firman mensajes con claves secretas grabadas en eFuses de forma invisible para el firmware.",
|
||||
"exemplo": "Permite autenticación rápida y segura con AWS IoT Core y Microsoft Azure IoT sin almacenar certificados en texto plano."
|
||||
},
|
||||
{
|
||||
"termo": "TRNG (Generador de números aleatorios verdaderos)",
|
||||
"definicao": "Generador de números aleatorios verdaderos basado en el ruido térmico analógico de los circuitos de radio y silicio, esencial para generar claves de sesión en handshakes TLS/HTTPS.",
|
||||
"exemplo": "Disponible en todas las series de ESP32 para garantizar entropía segura en conexiones HTTPS/MbedTLS."
|
||||
},
|
||||
{
|
||||
"termo": "Protección contra DPA (Differential Power Analysis)",
|
||||
"definicao": "Mecanismo físico de hardware que añade ruido y balanceo en el consumo de corriente eléctrica del chip para evitar que atacantes descubran claves criptográficas midiendo el consumo con osciloscopios.",
|
||||
"exemplo": "Presente en las series ESP32-C5, C6, C61 y H2."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "memoria",
|
||||
"nome": "Memoria, Buses y Almacenamiento",
|
||||
"icone": "Database",
|
||||
"emoji": "💾",
|
||||
"cor": "purple",
|
||||
"descricao": "SRAM, PSRAM externa, buses QSPI y Octal SPI, ROM de arranque, memoria RTC y sistemas de archivos.",
|
||||
"termos": [
|
||||
{
|
||||
"termo": "SRAM interna (Static RAM)",
|
||||
"definicao": "Memoria de acceso aleatorio de ultra alta velocidad integrada en el silicio, dividida en IRAM (instrucciones) y DRAM (datos). No pierde datos mientras el chip esté alimentado en modo activo.",
|
||||
"exemplo": "El ESP32 dispone de 520 KB de SRAM, mientras que el ESP32-P4 ofrece 768 KB de SRAM de alto rendimiento."
|
||||
},
|
||||
{
|
||||
"termo": "ROM de arranque (Boot ROM)",
|
||||
"definicao": "Memoria de solo lectura grabada durante la fabricación del silicio. Contiene el código de arranque primario (First-Stage Bootloader), rutinas de descarga serie y funciones criptográficas básicas.",
|
||||
"exemplo": "No puede ser alterada por el usuario ni infectada por malware; es la raíz de confianza de todo el chip."
|
||||
},
|
||||
{
|
||||
"termo": "Flash SPI (Quad-SPI vs Octal-SPI)",
|
||||
"definicao": "Interfaz de comunicación con memorias Flash externas. Quad-SPI (QSPI) usa 4 líneas de datos, mientras que Octal SPI (OPI) usa 8 líneas simultáneas con soporte DDR, duplicando la tasa de transferencia.",
|
||||
"exemplo": "Octal SPI en ESP32-S3 y ESP32-P4 permite tasas de lectura superiores a 120 MB/s para código y recursos multimedia."
|
||||
},
|
||||
{
|
||||
"termo": "PSRAM (Pseudo-Static RAM externa)",
|
||||
"definicao": "Memoria RAM dinámica externa empaquetada junto al chip (SiP) o conectada vía bus SPI/QSPI/OPI que expande la memoria disponible para buffers gráficos, audio y modelos de IA.",
|
||||
"exemplo": "Módulos ESP32-WROVER y ESP32-S3 disponen de 2 MB a 16 MB de PSRAM; ESP32-P4 admite hasta 32 MB."
|
||||
},
|
||||
{
|
||||
"termo": "SRAM RTC Fast y Slow",
|
||||
"definicao": "Pequeños bloques de memoria SRAM (típicamente 8 KB a 32 KB) ubicados en el dominio de energía de bajo consumo (RTC / Low Power). Conservan su contenido durante el Deep Sleep.",
|
||||
"exemplo": "Variables declaradas con `RTC_DATA_ATTR` mantienen su valor entre reinicios tras despertar de Deep Sleep."
|
||||
},
|
||||
{
|
||||
"termo": "Asignación DMA (MALLOC_CAP_DMA)",
|
||||
"definicao": "Solicitud de bloques de memoria RAM con direccionamiento físico continuo y accesibles por controladores DMA (Direct Memory Access) para transmisiones de alta velocidad sin intervención de la CPU.",
|
||||
"exemplo": "Necesario para buffers de pantallas SPI/I8080, audio I2S, transceptores Wi-Fi y lecturas de tarjetas SD."
|
||||
},
|
||||
{
|
||||
"termo": "Fragmentación del heap",
|
||||
"definicao": "Degradación del espacio libre de memoria dinámica en múltiples bloques pequeños dispersos debido a asignaciones y liberaciones sucesivas (malloc/free), impidiendo asignar bloques grandes contiguos.",
|
||||
"exemplo": "Causa común de fallos en conexiones TLS o asignación de buffers de cámara tras horas de funcionamiento."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "conectividade",
|
||||
"nome": "Conectividad Inalámbrica y Protocolos",
|
||||
"icone": "Wifi",
|
||||
"emoji": "📡",
|
||||
"cor": "emerald",
|
||||
"descricao": "Wi-Fi 4/6, Bluetooth Classic, BLE 5.x, Zigbee 3.0, Thread 1.3, Matter y redes ESP-NOW.",
|
||||
"termos": [
|
||||
{
|
||||
"termo": "Wi-Fi 6 (802.11ax)",
|
||||
"definicao": "Nueva generación del estándar Wi-Fi que aporta mayor eficiencia espectral, menor latencia y menor consumo energético en entornos saturados mediante OFDMA y Target Wake Time (TWT).",
|
||||
"exemplo": "ESP32-C6 y ESP32-C5 soportan Wi-Fi 6 en 2.4 GHz; el ESP32-C5 añade compatibilidad con la banda de 5 GHz."
|
||||
},
|
||||
{
|
||||
"termo": "Wi-Fi Dual-Band (2.4 GHz y 5 GHz)",
|
||||
"definicao": "Capacidad de operar tanto en la banda tradicional de 2.4 GHz como en la banda más descongestionada y de mayor ancho de banda de 5 GHz.",
|
||||
"exemplo": "El ESP32-C5 es el primer chip de Espressif con radio Wi-Fi 6 de doble banda simultánea (2.4 GHz y 5 GHz)."
|
||||
},
|
||||
{
|
||||
"termo": "OFDMA (Acceso múltiple por división de frecuencias ortogonales)",
|
||||
"definicao": "Tecnología de modulación de Wi-Fi 6 que divide los canales de radio en subcanales diminutos (Resource Units - RU), permitiendo transmitir datos hacia y desde múltiples dispositivos en un mismo instante.",
|
||||
"exemplo": "Reduce drásticamente la latencia en redes con cientos de sensores IoT conectados al mismo punto de acceso Wi-Fi 6."
|
||||
},
|
||||
{
|
||||
"termo": "TWT (Target Wake Time)",
|
||||
"definicao": "Mecanismo de ahorro de energía de Wi-Fi 6 que permite al punto de acceso y al dispositivo acordar ventanas de comunicación específicas, manteniendo el microcontrolador dormido durante horas entre transmisiones.",
|
||||
"exemplo": "Sensores a batería basados en ESP32-C6 multiplican su autonomía al conectarse a enrutadores Wi-Fi 6 con soporte TWT."
|
||||
},
|
||||
{
|
||||
"termo": "Bluetooth Classic (BR/EDR)",
|
||||
"definicao": "Modo tradicional de Bluetooth optimizado para streaming de audio continuo (perfil A2DP), transferencia de archivos y puertos serie SPP a tasas de datos de 2 a 3 Mbps.",
|
||||
"exemplo": "Disponible en el ESP32 original y en el ESP32-S31 para recepción y reproducción de música Bluetooth."
|
||||
},
|
||||
{
|
||||
"termo": "Bluetooth Low Energy (BLE 5.0 a 5.4)",
|
||||
"definicao": "Versión optimizada para consumo ultra bajo con soporte para modo de alta velocidad (2 Mbps), largo alcance (Coded PHY de 125/500 kbps) y extensiones publicitarias periódicas.",
|
||||
"exemplo": "Soportado en ESP32, S3, C3, C6, H2 y H4 para balizas, sensores corporales y aprovisionamiento de credenciales Wi-Fi."
|
||||
},
|
||||
{
|
||||
"termo": "Bluetooth LE Audio y Auracast",
|
||||
"definicao": "Nueva generación de audio Bluetooth basada en el códec LC3 de alta fidelidad y bajo consumo. Auracast permite transmitir audio en broadcast a un número ilimitado de receptores simultáneos.",
|
||||
"exemplo": "Soportado nativamente por el SoC ESP32-H4 para auriculares inalámbricos y sistemas de transmisión de audio accesible."
|
||||
},
|
||||
{
|
||||
"termo": "IEEE 802.15.4 (Zigbee 3.0 y Thread)",
|
||||
"definicao": "Estándar de radio de baja potencia y baja tasa de transferencia en 2.4 GHz que sirve de base física para redes en malla de automatización del hogar (Zigbee 3.0 y Thread 1.3).",
|
||||
"exemplo": "Chips como ESP32-H2 y ESP32-C6 cuentan con radio 802.15.4 para comunicación directa sin necesidad de Wi-Fi."
|
||||
},
|
||||
{
|
||||
"termo": "Matter (Estándar unificado de hogar inteligente)",
|
||||
"definicao": "Protocolo unificador de capa de aplicación respaldado por Apple, Google y la CSA. Funciona sobre Wi-Fi, Thread y Ethernet, garantizando interoperabilidad directa sin bridges propietarios.",
|
||||
"exemplo": "Un enchufe inteligente programado con ESP-Matter funciona simultáneamente en Apple HomeKit, Google Home y Home Assistant."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "perifericos",
|
||||
"nome": "Entradas, Salidas y Periféricos",
|
||||
"icone": "Sliders",
|
||||
"emoji": "🔌",
|
||||
"cor": "amber",
|
||||
"descricao": "GPIO, ADC, DAC, PWM (LEDC/MCPWM), UART, SPI, I2C, I2S y pines táctiles capacitivos.",
|
||||
"termos": [
|
||||
{
|
||||
"termo": "GPIO (Entradas y salidas de propósito general)",
|
||||
"definicao": "Pines digitales configurables como entradas (lectura de botones y sensores lógicos) o salidas (control de relés, LEDs y actuadores). Cuentan con resistencias pull-up y pull-down configurables por software.",
|
||||
"exemplo": "El ESP32 cuenta con hasta 34 GPIOs, mientras que el ESP32-S3 dispone de hasta 45 GPIOs multifuncionales."
|
||||
},
|
||||
{
|
||||
"termo": "Pines de arranque (Strapping Pins)",
|
||||
"definicao": "Pines GPIO específicos muestreados por el hardware durante el ciclo de reinicio (reset) para determinar el modo de arranque: ejecución normal desde Flash SPI, modo de descarga de firmware o configuración de voltajes LDO.",
|
||||
"exemplo": "GPIO0 y GPIO2 en ESP32, o GPIO8 y GPIO9 en ESP32-C3/C6. Circuitos externos no deben forzar niveles no deseados durante el arranque."
|
||||
},
|
||||
{
|
||||
"termo": "ADC (Convertidor analógico-digital)",
|
||||
"definicao": "Convertidor que transforma tensiones analógicas continuas en valores numéricos digitales (resolución de 12 bits, o 13 bits en ESP32-S2), con atenuaciones ajustables para rangos de hasta ~3.1V.",
|
||||
"exemplo": "ADC1 puede utilizarse simultáneamente con Wi-Fi, mientras que ADC2 comparte recursos de hardware con el subsistema de radio en algunos modelos."
|
||||
},
|
||||
{
|
||||
"termo": "DAC (Convertidor digital-analógico)",
|
||||
"definicao": "Convertidor por hardware que transforma números digitales en tensiones analógicas reales continuas (resolución de 8 bits), permitiendo generar ondas de sonido o voltajes de control.",
|
||||
"exemplo": "Presente en los pines GPIO25 y GPIO26 del ESP32 clásico y en el ESP32-S2 (los chips RISC-V prescinden de DAC analógico directo)."
|
||||
},
|
||||
{
|
||||
"termo": "LEDC (Controlador LED PWM)",
|
||||
"definicao": "Periférico por hardware diseñado para modulación por ancho de pulso (PWM) de alta precisión con desvanecimiento automático (fading) por hardware, configurable en múltiples canales y resoluciones de hasta 20 bits.",
|
||||
"exemplo": "Regulación de intensidad de tiras LED RGBW y servomotores sin ocupar tiempo de ejecución de la CPU."
|
||||
},
|
||||
{
|
||||
"termo": "MCPWM (PWM para control de motores)",
|
||||
"definicao": "Generador avanzado de PWM concebido para conmutación de puentes H, motores de corriente continua (DC), motores sin escobillas (BLDC) e inversores solares, con control de tiempo muerto (dead-time) y entradas de fallo (fault capture).",
|
||||
"exemplo": "Presente en ESP32, S3, C6 y P4 para accionamiento preciso de servomotores y robótica."
|
||||
},
|
||||
{
|
||||
"termo": "RMT (Periférico de control remoto)",
|
||||
"definicao": "Transmisor y receptor de trenes de pulsos precisos con temporización exacta de microsegundos, ideal para protocolos infrarrojos (NEC, RC5, Sony) y control de LEDs direccionables WS2812B (NeoPixel).",
|
||||
"exemplo": "Control de tiras de LEDs WS2812B con temporizaciones estrictas de 800 kHz sin bloquear interrupciones de la CPU."
|
||||
},
|
||||
{
|
||||
"termo": "PCNT (Contador de pulsos)",
|
||||
"definicao": "Periférico de hardware dedicado a contar flancos de subida y bajada de señales digitales de forma autónoma, sin generar interrupciones por cada pulso.",
|
||||
"exemplo": "Lectura de codificadores rotativos en cuadratura (rotary encoders), medidores de caudal de agua y anemómetros."
|
||||
},
|
||||
{
|
||||
"termo": "TWAI® (Interfaz automotriz de dos hilos / Bus CAN)",
|
||||
"definicao": "Controlador de red automotriz e industrial compatible con la especificación CAN 2.0B y CAN FD, resistente al ruido electromagnético severo con confirmación por hardware de tramas.",
|
||||
"exemplo": "Lectura de datos de telemetría de vehículos mediante conector OBD-II y comunicación en maquinaria pesada."
|
||||
},
|
||||
{
|
||||
"termo": "Pines táctiles capacitivos (Touch)",
|
||||
"definicao": "Circuitos analógicos integrados que miden variaciones diminutas de capacitancia eléctrica cuando un dedo humano se aproxima a una pista de cobre o almohadilla conductora.",
|
||||
"exemplo": "Permite crear botones táctiles detrás de vidrio o plástico y despertar el chip de Deep Sleep mediante toque."
|
||||
},
|
||||
{
|
||||
"termo": "PARLIO (Controlador de I/O paralelo)",
|
||||
"definicao": "Interfaz paralela flexible de alta velocidad de Espressif con soporte para transmisión y recepción de datos de 1 a 16 bits sincronizados con reloj externo o interno.",
|
||||
"exemplo": "Presente en ESP32-C6 y P4 para comunicación de alta velocidad con memorias externas, cámaras y pantallas LCD."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "multimidia",
|
||||
"nome": "Multimedia, USB e Interfaces Avanzadas",
|
||||
"icone": "Sparkles",
|
||||
"emoji": "✨",
|
||||
"cor": "pink",
|
||||
"descricao": "Interfaces de cámara DVP y MIPI CSI, pantallas LCD RGB y MIPI DSI, USB OTG nativo y USB Serial/JTAG.",
|
||||
"termos": [
|
||||
{
|
||||
"termo": "USB OTG (On-The-Go) nativo",
|
||||
"definicao": "Controlador USB integrado que permite al chip actuar tanto como periférico USB (teclado HID, ratón, puerto serie CDC, almacenamiento masivo) como puerto Host USB para conectar memorias USB o cámaras.",
|
||||
"exemplo": "Soportado en ESP32-S2 y S3 a 12 Mbps (Full-Speed); ESP32-P4 cuenta con controlador USB 2.0 High-Speed a 480 Mbps."
|
||||
},
|
||||
{
|
||||
"termo": "USB Serial/JTAG nativo",
|
||||
"definicao": "Periférico de hardware que conecta directamente el puerto USB de la PC a los pines de depuración JTAG y consola serie del chip, eliminando la necesidad de chips conversores externos (como CP2102 o CH340).",
|
||||
"exemplo": "Disponible en ESP32-C3, C6, S3, C5 y H2 para carga de firmware y depuración con OpenOCD sin sondas adicionales."
|
||||
},
|
||||
{
|
||||
"termo": "USB 2.0 High-Speed (480 Mbps)",
|
||||
"definicao": "Controlador USB de alta velocidad con capa física integrada (PHY High-Speed) que multiplica por 40 la velocidad de transferencia frente al USB Full-Speed (12 Mbps).",
|
||||
"exemplo": "Exclusivo del ESP32-P4 para transmisión de video en tiempo real y transferencia masiva de archivos."
|
||||
},
|
||||
{
|
||||
"termo": "MIPI CSI y MIPI DSI",
|
||||
"definicao": "Interfaces serie diferenciales de ultra alta velocidad estándar de la industria móvil para sensores de cámara (CSI) y pantallas gráficas (DSI) de alta resolución.",
|
||||
"exemplo": "Presentes en el ESP32-P4 con soporte de hasta 2 carriles a 1.5 Gbps por carril para video 1080p."
|
||||
},
|
||||
{
|
||||
"termo": "Codificador de video H.264 por hardware",
|
||||
"definicao": "Acelerador de compresión de video por hardware capaz de codificar secuencias de fotogramas en formato H.264 (AVC) a resoluciones de hasta 1080p a 30 FPS.",
|
||||
"exemplo": "Exclusivo del ESP32-P4 para cámaras de seguridad IP y videoporteros sin sobrecargar la CPU."
|
||||
},
|
||||
{
|
||||
"termo": "Ethernet MAC 10/100 Mbps",
|
||||
"definicao": "Controlador de capa de enlace Ethernet integrado en silicio que requiere únicamente un chip transceptor físico externo (PHY como LAN8720 o IP101) conectado vía bus RMII.",
|
||||
"exemplo": "Disponible en el ESP32 clásico y en el ESP32-P4 para conexiones de red por cable ultra estables sin interferencias de RF."
|
||||
},
|
||||
{
|
||||
"termo": "Interfaz de cámara DVP (8 bits / 16 bits)",
|
||||
"definicao": "Interfaz de cámara paralela de 8 a 16 bits sincronizada por reloj de píxel (PCLK), sincronización horizontal (HREF) y vertical (VSYNC), diseñada para sensores de imagen tipo OV2640 y OV5640.",
|
||||
"exemplo": "Utilizada en placas como ESP32-CAM y ESP32-S3-EYE para captura y streaming de video MJPEG."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "energia",
|
||||
"nome": "Gestión de Energía y Modos de Suspensión",
|
||||
"icone": "BatteryCharging",
|
||||
"emoji": "🔋",
|
||||
"cor": "teal",
|
||||
"descricao": "Modo activo, Modem Sleep, Light Sleep, Deep Sleep, fuentes de activación y detección de brownout.",
|
||||
"termos": [
|
||||
{
|
||||
"termo": "Modo activo (Active Mode)",
|
||||
"definicao": "Estado de funcionamiento pleno en el que todos los núcleos de CPU, buses, periféricos y subsistemas de radio Wi-Fi/Bluetooth operan a su frecuencia nominal.",
|
||||
"exemplo": "Consumo típico de 30 a 60 mA en cómputo puro, con picos de 200 a 400 mA durante transmisiones RF."
|
||||
},
|
||||
{
|
||||
"termo": "Modem Sleep",
|
||||
"definicao": "Modo de ahorro de energía en el que la CPU continúa funcionando activamente pero el subsistema de radio Wi-Fi o Bluetooth apaga sus circuitos entre intervalos de baliza (DTIM).",
|
||||
"exemplo": "El ESP32 permanece asociado al router Wi-Fi consumiendo solo 20 a 40 mA mientras procesa datos locales."
|
||||
},
|
||||
{
|
||||
"termo": "Light Sleep",
|
||||
"definicao": "Modo en el que el reloj de la CPU se detiene y la mayor parte de los periféricos digitales se suspenden, pero la memoria RAM interna se preserva íntegramente. El retorno al modo activo es prácticamente instantáneo (< 1 ms).",
|
||||
"exemplo": "Consumo de corriente reducido a 0.8–2.0 mA; puede despertarse por temporizador, pines GPIO, UART o eventos Wi-Fi."
|
||||
},
|
||||
{
|
||||
"termo": "Deep Sleep",
|
||||
"definicao": "Modo de suspensión profunda en el que la CPU principal, periféricos y SRAM estándar se desenergizan por completo. Solo el dominio RTC/LP y su memoria de bajo consumo permanecen activos.",
|
||||
"exemplo": "Consumo de corriente diminuto de 5 a 150 µA, permitiendo que sensores autónomos operen durante años con una única batería."
|
||||
},
|
||||
{
|
||||
"termo": "Hibernación (Hibernation Mode)",
|
||||
"definicao": "El modo de consumo más bajo posible del chip: todos los osciladores internos y memorias se apagan, manteniendo solo un temporizador ultralento o un pin de reactivación externo.",
|
||||
"exemplo": "Consumo residual tan bajo como 5 µA; al despertar, el chip ejecuta un reinicio completo (reboot)."
|
||||
},
|
||||
{
|
||||
"termo": "Fuentes de activación (Wakeup Sources)",
|
||||
"definicao": "Eventos de hardware configurados para reactivar el microcontrolador desde Light Sleep o Deep Sleep.",
|
||||
"exemplo": "Temporizador RTC (Timer), interrupción por pin táctil (Touch), cambio de nivel lógico en pines GPIO (ext0/ext1) o eventos del coprocesador ULP."
|
||||
},
|
||||
{
|
||||
"termo": "Detector de subtensión (Brownout Detector)",
|
||||
"definicao": "Circuito comparador analógico interno que monitorea continuamente la tensión del riel de 3.3V y reinicia el chip de forma segura si el voltaje cae por debajo del umbral crítico (~2.43V).",
|
||||
"exemplo": "Evita la corrupción de datos en la memoria Flash SPI durante caídas transitorias de tensión provocadas por picos de transmisión Wi-Fi."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "desenvolvimento",
|
||||
"nome": "Firmware, Arranque y Sistema Operativo",
|
||||
"icone": "Code2",
|
||||
"emoji": "🚀",
|
||||
"cor": "rose",
|
||||
"descricao": "Bootloader, tabla de particiones, FreeRTOS, ESP-IDF, IDF Component Manager y actualizaciones OTA.",
|
||||
"termos": [
|
||||
{
|
||||
"termo": "Bootloader (Primera y segunda etapa)",
|
||||
"definicao": "Proceso de arranque en dos fases: la ROM interna (1ª etapa) verifica los pines de arranque e inicia el Second-Stage Bootloader ubicado en la Flash, el cual carga la tabla de particiones y transfiere el control a la aplicación.",
|
||||
"exemplo": "Permite seleccionar entre múltiples particiones de firmware (fábrica, OTA_0, OTA_1) según el estado del sistema."
|
||||
},
|
||||
{
|
||||
"termo": "FreeRTOS (Sistema operativo de tiempo real)",
|
||||
"definicao": "Sistema operativo de tiempo real adaptado por Espressif para multitarea simétrica multinúcleo (Symmetric Multiprocessing - SMP), administrando colas, semáforos, mutexes y prioridades de tareas en ambos núcleos.",
|
||||
"exemplo": "Creación de tareas independientes con `xTaskCreatePinnedToCore()` fijadas específicamente al Core 0 o al Core 1."
|
||||
},
|
||||
{
|
||||
"termo": "Atributos IRAM_ATTR y DRAM_ATTR",
|
||||
"definicao": "Macros de compilación del ESP-IDF que fuerzan la ubicación de funciones en la memoria interna IRAM (en lugar de la Flash SPI) o datos en DRAM, requisito indispensable para rutinas de interrupción (ISRs).",
|
||||
"exemplo": "Previene caídas por Guru Meditation si ocurre una interrupción mientras la memoria Flash SPI se encuentra ocupada escribiendo datos."
|
||||
},
|
||||
{
|
||||
"termo": "Tabla de particiones (partitions.csv)",
|
||||
"definicao": "Archivo de configuración que divide el espacio de la memoria Flash SPI en sectores lógicos con propósitos específicos: bootloader, datos de calibración NVS, aplicaciones de firmware y sistemas de archivos.",
|
||||
"exemplo": "Configuración esencial para habilitar particiones duales de actualización inalámbrica OTA (`ota_0` y `ota_1`)."
|
||||
},
|
||||
{
|
||||
"termo": "Actualizaciones OTA con Rollback",
|
||||
"definicao": "Mecanismo que permite actualizar el firmware de dispositivos conectados vía Wi-Fi, Ethernet o BLE, escribiendo la nueva versión en una partición secundaria y alternando el puntero de arranque de forma atómica.",
|
||||
"exemplo": "Cuenta con soporte para reversión automática (rollback) si el nuevo firmware falla en su primera ejecución."
|
||||
},
|
||||
{
|
||||
"termo": "NVS (Non-Volatile Storage) y cifrado NVS",
|
||||
"definicao": "Biblioteca y partición de almacenamiento en memoria Flash organizada en pares clave-valor. Incluye balanceo de desgaste (wear leveling) y cifrado con claves basadas en eFuses para datos sensibles de configuración.",
|
||||
"exemplo": "Utilizada por el ESP-IDF para guardar credenciales Wi-Fi (SSID/contraseña) y claves criptográficas de forma segura."
|
||||
},
|
||||
{
|
||||
"termo": "Sistemas de archivos (LittleFS y SPIFFS)",
|
||||
"definicao": "Estructuras de archivos sobre memoria Flash SPI. LittleFS es el estándar moderno, más rápido, resistente a fallos de alimentación y con menor sobrecarga de RAM que el obsoleto SPIFFS.",
|
||||
"exemplo": "Almacenamiento de páginas web (HTML/CSS/JS), imágenes de interfaz y certificados SSL en la memoria Flash local."
|
||||
},
|
||||
{
|
||||
"termo": "JTAG y OpenOCD",
|
||||
"definicao": "Estándar de depuración por hardware que permite pausar la ejecución de la CPU, inspeccionar el valor de registros, recorrer el código paso a paso y evaluar puntos de interrupción en tiempo real.",
|
||||
"exemplo": "Depuración integrada mediante USB Serial/JTAG en ESP32-S3/C3/C6 o mediante sondas externas como ESP-PROG."
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* Conocimiento de dominio para la búsqueda inteligente en español.
|
||||
*
|
||||
* Sin dependencias ni alias de import: se ejecuta en el servidor (montando el índice),
|
||||
* en el navegador (interpretando la consulta) y en scripts de prueba en Node.
|
||||
*
|
||||
* Todos los textos de `termos` ya están normalizados (minúsculas, sin acentos).
|
||||
*/
|
||||
|
||||
export const normalizar = (s = "") =>
|
||||
String(s)
|
||||
.toLowerCase()
|
||||
.normalize("NFD")
|
||||
.replace(/[\u0300-\u036f]/g, "");
|
||||
|
||||
/**
|
||||
* Reconoce pines ocupados por flash/PSRAM según la descripción del diagrama.
|
||||
* "forte": el pin es consumido por la memoria (o es su alimentación).
|
||||
* "fraco": solo se ve afectado en ciertos modos (ej.: SPI de 8 líneas/octal).
|
||||
*/
|
||||
const nivelMemoria = (palabra) => (p) => {
|
||||
const citam = p._avs.filter((a) => a.includes(palabra) && !/^para chips (con|sin|com|sem)/i.test(a));
|
||||
if (citam.some((a) => /(utilizad|dedicad|conectad)/i.test(a) && !/a menos que/i.test(a))) return "forte";
|
||||
if (p._fn.some((f) => /alimentacion|alimentacao/i.test(f) && f.includes(palabra))) return "forte";
|
||||
if (citam.length) return "fraco";
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Temas que el usuario puede consultar en español.
|
||||
*/
|
||||
export const TOPICOS = [
|
||||
{ id: "flash", nome: "Flash", termos: ["flash", "memoria flash", "spi flash", "almacenamiento", "firmware", "rom externa"], pinoNivel: nivelMemoria("flash"), pinoRotulo: "conectados a la memoria flash" },
|
||||
{ id: "psram", nome: "PSRAM", termos: ["psram", "ram externa", "spiram"], pinoNivel: nivelMemoria("psram"), pinoRotulo: "conectados a la PSRAM" },
|
||||
{ id: "memoria", nome: "Memoria", termos: ["memoria", "sram", "heap", "rtc ram", "kb de ram", "memoria interna", "ram", "memory"], pinoRotulo: "" },
|
||||
{ id: "wifi", nome: "Wi-Fi", termos: ["wifi", "wi-fi", "inalambrico", "wireless", "sin cable", "802.11", "wifi6", "wifi 6", "wi-fi 6"], pinoCats: ["Antena"], pinoRotulo: "de antena y radio" },
|
||||
{ id: "bluetooth", nome: "Bluetooth", termos: ["bluetooth", "ble", "bt", "bluetooth le", "mesh"], pinoCats: ["Antena"], pinoRotulo: "de antena y radio" },
|
||||
{ id: "zigbee", nome: "Zigbee/Thread", termos: ["zigbee", "thread", "802.15.4", "ieee 802.15.4"], pinoRotulo: "" },
|
||||
{ id: "matter", nome: "Matter", termos: ["matter", "hogar inteligente", "smart home", "casa inteligente"], pinoRotulo: "" },
|
||||
{ id: "ethernet", nome: "Ethernet", termos: ["ethernet", "rmii", "cable de red", "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 / Depuración", termos: ["jtag", "debug", "depuracion", "depurar", "openocd", "gdb"], pinoCats: ["JTAG"], pinoRotulo: "de JTAG" },
|
||||
{ id: "adc", nome: "ADC", termos: ["adc", "analogico", "entrada analogica", "convertidor analogico", "analogread", "saradc"], pinoCats: ["ADC"], pinoRotulo: "con ADC" },
|
||||
{ id: "dac", nome: "DAC", termos: ["dac", "salida analogica", "convertidor digital"], pinoCats: ["DAC"], pinoRotulo: "con DAC" },
|
||||
{ id: "touch", nome: "Táctil capacitivo", termos: ["touch", "capacitivo", "tactil", "toque", "touchpad", "sensor tactil"], pinoCats: ["Touch"], pinoRotulo: "de táctil capacitivo" },
|
||||
{ id: "uart", nome: "UART", termos: ["uart", "serial", "tx", "rx", "txd", "rxd", "puerto serie"], pinoCats: ["UART"], pinoRotulo: "de UART" },
|
||||
{ id: "spi", nome: "SPI", termos: ["spi", "mosi", "miso", "sclk", "bus 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", "sonido", "microfono", "pdm", "codec"], pinoRe: /i2s|\bpdm\b/, pinoRotulo: "de I2S / audio" },
|
||||
{ id: "pwm", nome: "PWM", termos: ["pwm", "ledc", "mcpwm", "servo", "dimmer"], pinoRe: /ledc|pwm/, pinoRotulo: "de PWM" },
|
||||
{ id: "sd", nome: "Tarjeta SD / SDIO", termos: ["sd", "sdio", "sd card", "sdcard", "tarjeta sd", "microsd", "sdmmc", "mmc"], pinoCats: ["SD"], pinoRe: /sdio|sdmmc|\bsd\b/, pinoRotulo: "de tarjeta SD/SDIO" },
|
||||
{ id: "camera", nome: "Cámara", termos: ["camera", "camara", "cam", "dvp", "csi", "mipi csi", "ov2640", "video"], pinoCats: ["CSI"], pinoRe: /\bcam\b|dvp|cam_/, pinoRotulo: "de cámara" },
|
||||
{ id: "lcd", nome: "Pantalla / LCD", termos: ["lcd", "display", "pantalla", "dsi", "mipi dsi", "oled", "tft", "lvgl", "rgb"], pinoCats: ["DSI"], pinoRe: /lcd/, pinoRotulo: "de pantalla/LCD" },
|
||||
{ id: "strapping", nome: "Boot / Strapping", termos: ["strapping", "boot", "bootstrap", "modo de boot", "modo de arranque", "download mode", "modo de grabacion", "arranque"], pinoCats: ["Strapping"], pinoRotulo: "de strapping (modo de arranque)" },
|
||||
{ id: "energia_pinos", nome: "Alimentación", termos: ["alimentacion", "vdd", "3v3", "3.3v", "tension", "regulador", "ldo", "fuente"], pinoCats: ["Power"], pinoRotulo: "de alimentación" },
|
||||
{ id: "clock", nome: "Reloj / Cristal", termos: ["clock", "reloj", "xtal", "cristal", "oscilador", "32khz", "40mhz"], pinoCats: ["Clock"], pinoRotulo: "de reloj/cristal" },
|
||||
{ id: "gpio", nome: "GPIO", termos: ["gpio", "entradas y salidas", "pines"], pinoCats: ["GPIO"], pinoRotulo: "de GPIO" },
|
||||
{ id: "baixo_consumo", nome: "Bajo consumo / ULP", termos: ["ulp", "lp core", "lp cpu", "coprocesador", "lp gpio", "low power", "rtc gpio", "bajo consumo"], pinoCats: ["Low Power"], pinoRotulo: "de bajo consumo (LP/RTC)" },
|
||||
{ id: "antena", nome: "Antena / RF", termos: ["antena", "rf", "radiofrecuencia", "ipex"], pinoCats: ["Antena"], pinoRotulo: "de antena/RF" },
|
||||
{ id: "seguranca", nome: "Seguridad", termos: ["seguridad", "seguranca", "secure boot", "criptografia", "cifrado", "aes", "sha", "rsa", "hmac", "ecdsa", "efuse", "tee", "trng", "rng", "hsm", "proteccion"], pinoRotulo: "" },
|
||||
{ id: "consumo", nome: "Consumo de energía", termos: ["consumo", "bateria", "deep sleep", "light sleep", "sleep", "modem sleep", "corriente", "miliamperios", "autonomia", "ahorro de energia", "modo bajo consumo"], pinoRotulo: "" },
|
||||
{ id: "temperatura", nome: "Temperatura", termos: ["temperatura", "calor", "grados", "rango de temperatura", "industrial"], pinoRotulo: "" },
|
||||
{ id: "ia", nome: "IA / Aceleración", termos: ["ia", "ai", "machine learning", "ml", "tinyml", "vectorial", "inteligencia artificial", "red neuronal", "esp-nn", "esp-dl"], pinoRotulo: "" },
|
||||
{ id: "processador", nome: "Procesador", termos: ["procesador", "cpu", "nucleo", "nucleos", "core", "dual core", "single core", "arquitectura", "xtensa", "risc-v", "riscv"], pinoRotulo: "" },
|
||||
{ id: "frequencia", nome: "Frecuencia", termos: ["frecuencia", "mhz", "velocidad", "rendimiento", "performance"], pinoRotulo: "" },
|
||||
{ id: "ferramentas", nome: "Herramientas / SDK", termos: ["esp-idf", "idf", "arduino", "sdk", "toolchain", "cadena de herramientas", "version de idf"], pinoRotulo: "" },
|
||||
{ id: "encapsulamento", nome: "Módulos y encapsulado", termos: ["modulo", "modulos", "encapsulado", "package", "qfn", "wroom", "wrover", "mini-1"], pinoRotulo: "" },
|
||||
];
|
||||
|
||||
/**
|
||||
* Campos de datos que responden a cada tema en español.
|
||||
*/
|
||||
export const SPEC_CAMPOS = [
|
||||
{ campo: "arquitetura", label: "Arquitectura", secao: "processador", topicos: ["processador"] },
|
||||
{ campo: "nucleos", label: "Núcleos", secao: "processador", topicos: ["processador"] },
|
||||
{ campo: "frequencia", label: "Frecuencia", secao: "processador", topicos: ["frequencia", "processador"] },
|
||||
{ campo: "coprocessador_ulp", label: "Coprocesador 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: "Táctil capacitivo", 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ámara", 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: "Firma digital", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.rng", label: "Generador de números aleatorios", secao: "seguranca", topicos: ["seguranca"] },
|
||||
{ campo: "seguranca.criptografia_flash", label: "Cifrado 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 operación", secao: "temperatura", topicos: ["temperatura"] },
|
||||
{ campo: "temperatura_armazenamento", label: "Temperatura de almacenamiento", secao: "temperatura", topicos: ["temperatura"] },
|
||||
|
||||
{ campo: "esp_idf_minimo", label: "ESP-IDF mínimo", secao: "ferramentas", topicos: ["ferramentas"] },
|
||||
{ campo: "arduino_core", label: "Arduino Core", secao: "ferramentas", topicos: ["ferramentas"] },
|
||||
{ campo: "depuracao", label: "Depuración", secao: "ferramentas", topicos: ["jtag", "ferramentas"] },
|
||||
{ campo: "encapsulamento", label: "Encapsulado", secao: "ferramentas", topicos: ["encapsulamento"] },
|
||||
{ campo: "modulos", label: "Módulos", secao: "ferramentas", topicos: ["encapsulamento"] },
|
||||
];
|
||||
|
||||
const ROTULOS_ENERGIA = {
|
||||
active: "Activo",
|
||||
modem_sleep: "Modem Sleep",
|
||||
light_sleep: "Light Sleep",
|
||||
deep_sleep: "Deep Sleep",
|
||||
hibernation: "Hibernación",
|
||||
};
|
||||
|
||||
const pegar = (obj, caminho) => caminho.split(".").reduce((o, k) => (o == null ? o : o[k]), obj);
|
||||
|
||||
/**
|
||||
* Monta la lista plana de especificaciones para cada serie en español.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
+104
-17
@@ -1,9 +1,24 @@
|
||||
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 seriesDataEs from "@/data/es/series.json";
|
||||
import frameworksDataEs from "@/data/es/frameworks.json";
|
||||
import { categoriasGlossario as glossarioEs } from "@/lib/data/es/glossario";
|
||||
import { errosCatalogo as errosEs } from "@/lib/data/es/diagnostico";
|
||||
import { COMPONENTES_REGISTRY as componentesEs } from "@/lib/data/es/componentes";
|
||||
import { montarConhecimento as montarConhecimentoEs } from "@/lib/data/es/topicos";
|
||||
|
||||
import { readFileSync, existsSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
@@ -15,7 +30,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 +44,74 @@ 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 PAGINAS_ES = [
|
||||
{ titulo: "Inicio", descricao: "Página de inicio de ESPDocs", href: "/es", keywords: "home inicio" },
|
||||
{ titulo: "Todas las Series", descricao: "Distribución de pines, especificaciones y restricciones de cada serie ESP32", href: "/es/series", keywords: "chips distribución de pines especificaciones" },
|
||||
{ titulo: "Comparador de Series", descricao: "Compare hasta 4 modelos lado a lado", href: "/es/comparacion", keywords: "comparar comparación versus" },
|
||||
{ titulo: "Catálogo de Placas", descricao: "Placas de desarrollo, conectores y compras", href: "/es/catalogo", keywords: "placas dev boards comprar devkit" },
|
||||
{ titulo: "Selector Inteligente", descricao: "Descubra el chip ideal para su proyecto", href: "/es/selector", keywords: "quiz elegir recomendar selector" },
|
||||
{ titulo: "Diagnóstico de Errores", descricao: "Solucione brownout, bucles de arranque, WDT y fallos", href: "/es/diagnostico", keywords: "error problema fallo crash" },
|
||||
{ titulo: "Frameworks y SDKs", descricao: "ESP-IDF, Arduino, Rust, RainMaker y más", href: "/es/frameworks", keywords: "sdk" },
|
||||
{ titulo: "Component Registry", descricao: "Catálogo de controladores y generador de idf_component.yml", href: "/es/componentes", keywords: "bibliotecas controladores drivers yml" },
|
||||
{ titulo: "Glosario Técnico", descricao: "Conceptos esenciales de hardware y software", href: "/es/glosario", keywords: "términos diccionario significado" },
|
||||
{ titulo: "Acerca del Proyecto", descricao: "Historia, autor y código abierto", href: "/es/acerca", keywords: "autor contacto código abierto" },
|
||||
];
|
||||
|
||||
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 isEs = locale === "es";
|
||||
|
||||
let paginas = PAGINAS_PT;
|
||||
let seriesData = seriesDataPt;
|
||||
let frameworksData = frameworksDataPt;
|
||||
let categoriasGlossario = glossarioPt;
|
||||
let errosCatalogo = errosPt;
|
||||
let componentes = componentesPt;
|
||||
let montarConhecimento = montarConhecimentoPt;
|
||||
|
||||
if (isEn) {
|
||||
paginas = PAGINAS_EN;
|
||||
seriesData = seriesDataEn;
|
||||
frameworksData = frameworksDataEn;
|
||||
categoriasGlossario = glossarioEn;
|
||||
errosCatalogo = errosEn;
|
||||
componentes = componentesEn;
|
||||
montarConhecimento = montarConhecimentoEn;
|
||||
} else if (isEs) {
|
||||
paginas = PAGINAS_ES;
|
||||
seriesData = seriesDataEs;
|
||||
frameworksData = frameworksDataEs;
|
||||
categoriasGlossario = glossarioEs;
|
||||
errosCatalogo = errosEs;
|
||||
componentes = componentesEs;
|
||||
montarConhecimento = montarConhecimentoEs;
|
||||
}
|
||||
|
||||
const prefixo = isEn ? "/en" : isEs ? "/es" : "";
|
||||
const slugSeries = `${prefixo}/series`;
|
||||
const slugFrameworks = `${prefixo}/frameworks`;
|
||||
const slugGlossario = isEn ? "/en/glossary" : isEs ? "/es/glosario" : "/glossario";
|
||||
const slugDiagnostico = isEn ? "/en/diagnostics" : isEs ? "/es/diagnostico" : "/diagnostico";
|
||||
const slugComponentes = isEn ? "/en/components" : isEs ? "/es/componentes" : "/componentes";
|
||||
|
||||
const itens = [];
|
||||
|
||||
for (const p of PAGINAS) {
|
||||
for (const p of paginas) {
|
||||
itens.push({ tipo: "pagina", ...p, keywords: p.keywords });
|
||||
}
|
||||
|
||||
@@ -43,7 +120,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 +130,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 +142,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 +153,35 @@ 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")
|
||||
: isEs
|
||||
? path.join(process.cwd(), "data", "es", "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 {
|
||||
|
||||
+127
-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 === "es" ? "es-419" : 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,30 @@ export function paginaMeta({ titulo, descricao, caminho, keywords = [], tipo = "
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
export const jsonLd = {
|
||||
siteESociedade() {
|
||||
siteESociedade(locale = "pt") {
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const orgAnchor = isEn ? "organization" : isEs ? "organizacion" : "organizacao";
|
||||
const authorAnchor = isEn ? "author" : "autor";
|
||||
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" : isEs ? "es-419" : "pt-BR",
|
||||
description: isEn
|
||||
? "ESP32 ecosystem documentation: specifications, pinouts, comparison, and series selection."
|
||||
: isEs
|
||||
? "Documentación del ecosistema ESP32: especificaciones, patillaje, comparación y selección de series."
|
||||
: "Documentação do ecossistema ESP32 em português brasileiro: especificações, pinagem, comparação e seleção de séries.",
|
||||
publisher: { "@id": `${SITE.url}/#${orgAnchor}` },
|
||||
},
|
||||
{
|
||||
"@type": "Organization",
|
||||
"@id": `${SITE.url}/#organizacao`,
|
||||
"@id": `${SITE.url}/#${orgAnchor}`,
|
||||
name: "Ciência Embarcada",
|
||||
url: SITE.blog,
|
||||
logo: {
|
||||
@@ -87,7 +129,7 @@ export const jsonLd = {
|
||||
},
|
||||
{
|
||||
"@type": "Person",
|
||||
"@id": `${SITE.url}/#autor`,
|
||||
"@id": `${SITE.url}/#${authorAnchor}`,
|
||||
name: SITE.autor,
|
||||
url: SITE.autorUrl,
|
||||
email: SITE.autorEmail,
|
||||
@@ -112,44 +154,57 @@ 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 isEs = locale === "es";
|
||||
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" : isEs ? "Fabricante" : "Fabricante", "Espressif Systems"),
|
||||
prop(isEn ? "Architecture" : isEs ? "Arquitectura" : "Arquitetura", serie.arquitetura),
|
||||
prop(isEn ? "Cores" : isEs ? "Núcleos" : "Núcleos", serie.nucleos),
|
||||
prop(isEn ? "Max frequency" : isEs ? "Frecuencia máxima" : "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" : isEs ? "Flash soportada" : "Flash suportada", serie.flash_suportada),
|
||||
prop(isEn ? "Supported PSRAM" : isEs ? "PSRAM soportada" : "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" : isEs ? "Encapsulado" : "Encapsulamento", serie.encapsulamento),
|
||||
prop(isEn ? "Minimum ESP-IDF" : isEs ? "ESP-IDF mínimo" : "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}` : isEs ? `/es/series/${chave}` : `/series/${chave}`;
|
||||
const anchor = isEn ? "article" : isEs ? "articulo" : "artigo";
|
||||
|
||||
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}#${anchor}`,
|
||||
headline: isEn
|
||||
? `${serie.nome_completo || chave}: specifications and pinout`
|
||||
: isEs
|
||||
? `${serie.nome_completo || chave}: especificaciones y patillaje`
|
||||
: `${serie.nome_completo || chave}: especificações e pinagem`,
|
||||
name: isEn
|
||||
? `${serie.nome_completo || chave} - Technical Documentation and Specifications`
|
||||
: isEs
|
||||
? `${serie.nome_completo || chave} - Documentación técnica y especificaciones`
|
||||
: `${serie.nome_completo || chave} - Documentação Técnica e Especificações`,
|
||||
description: serie.descricao,
|
||||
image: [imagem],
|
||||
inLanguage: "pt-BR",
|
||||
inLanguage: isEn ? "en" : isEs ? "es-419" : "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 +231,30 @@ export const jsonLd = {
|
||||
},
|
||||
|
||||
/** Documentação técnica de framework. */
|
||||
framework(chave, framework) {
|
||||
framework(chave, framework, locale = "pt") {
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const basePath = isEn ? `/en/frameworks/${encodeURIComponent(chave)}` : isEs ? `/es/frameworks/${encodeURIComponent(chave)}` : `/frameworks/${encodeURIComponent(chave)}`;
|
||||
const anchor = isEn ? "article" : isEs ? "articulo" : "artigo";
|
||||
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}#${anchor}`,
|
||||
headline: isEn
|
||||
? `${framework.nome} for ESP32: Guide and Documentation`
|
||||
: isEs
|
||||
? `${framework.nome} para ESP32: Guía y documentación`
|
||||
: `${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" : isEs ? "es-419" : "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 +277,29 @@ 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 isEs = locale === "es";
|
||||
const basePath = isEn ? "/en/glossary" : isEs ? "/es/glosario" : "/glossario";
|
||||
const anchor = isEn ? "glossary" : isEs ? "glosario" : "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}#${anchor}`,
|
||||
name: isEn ? "ESP32 Technical Glossary" : isEs ? "Glosario técnico de ESP32" : "Glossário Técnico do ESP32",
|
||||
inLanguage: isEn ? "en" : isEs ? "es-419" : "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}#${anchor}`,
|
||||
}))
|
||||
),
|
||||
};
|
||||
@@ -250,7 +319,9 @@ 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";
|
||||
const isEs = locale === "es";
|
||||
return {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebApplication",
|
||||
@@ -261,7 +332,7 @@ export const jsonLd = {
|
||||
applicationCategory: "DeveloperApplication",
|
||||
operatingSystem: "All",
|
||||
browserRequirements: "Requires JavaScript",
|
||||
inLanguage: "pt-BR",
|
||||
inLanguage: isEn ? "en" : isEs ? "es-419" : "pt-BR",
|
||||
author: {
|
||||
"@type": "Person",
|
||||
name: SITE.autor,
|
||||
@@ -341,15 +412,23 @@ 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 isEs = locale === "es";
|
||||
const basePath = isEn ? "/en/about" : isEs ? "/es/acerca" : "/sobre";
|
||||
const anchor = isEn ? "about" : isEs ? "acerca" : "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}#${anchor}`,
|
||||
name: isEn ? "About ESPDocs" : isEs ? "Acerca de ESPDocs" : "Sobre o ESPDocs",
|
||||
description: isEn
|
||||
? "ESPDocs is an independent platform organizing technical documentation of the ESP32 ecosystem."
|
||||
: isEs
|
||||
? "ESPDocs es una plataforma independiente que reúne la documentación técnica del ecosistema ESP32."
|
||||
: "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" : isEs ? "es-419" : "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,152 @@
|
||||
{
|
||||
"Common": {
|
||||
"siteName": "ESPDocs",
|
||||
"author": "Lucas Rayan Guerra",
|
||||
"organization": "Ciência Embarcada",
|
||||
"skipToContent": "Saltar al contenido",
|
||||
"allRightsReserved": "Contenido bajo licencia MIT. Hecho para la comunidad de sistemas embebidos.",
|
||||
"backToHome": "Volver al inicio",
|
||||
"explore": "Explorar",
|
||||
"tools": "Herramientas",
|
||||
"project": "Proyecto",
|
||||
"loading": "Cargando...",
|
||||
"search": "Buscar...",
|
||||
"officialDocumentation": "Documentación oficial",
|
||||
"community": "Comunidad",
|
||||
"mitLicense": "Licencia MIT"
|
||||
},
|
||||
"Header": {
|
||||
"brand": "ESPDocs",
|
||||
"homeAria": "ESPDocs, página de inicio",
|
||||
"navAria": "Navegación principal",
|
||||
"mobileNavAria": "Navegación móvil",
|
||||
"openMenu": "Abrir menú de navegación",
|
||||
"closeMenu": "Cerrar menú",
|
||||
"navigationTitle": "Navegación",
|
||||
"whereToGo": "A dónde ir",
|
||||
"selectChip": "Seleccionar chip",
|
||||
"selectMyChip": "Seleccionar mi chip",
|
||||
"hardware": "Hardware",
|
||||
"hardwareDesc": "12 chips, distribución de pines y especificaciones",
|
||||
"series": "Series ESP32",
|
||||
"seriesDesc": "12 chips, distribución de pines y especificaciones",
|
||||
"comparator": "Comparador",
|
||||
"comparatorDesc": "Hasta cuatro series lado a lado",
|
||||
"catalog": "Catálogo de placas",
|
||||
"catalogDesc": "DevKits, distribución de pines y dónde comprar",
|
||||
"tools": "Herramientas",
|
||||
"selector": "Selector inteligente",
|
||||
"selectorDesc": "El chip adecuado para su proyecto",
|
||||
"diagnostics": "Diagnóstico",
|
||||
"diagnosticsDesc": "Brownout, bucles de arranque, WDT y más",
|
||||
"components": "Component Registry",
|
||||
"componentsDesc": "Controladores y manifiestos idf_component.yml",
|
||||
"library": "Biblioteca",
|
||||
"frameworks": "Frameworks y SDKs",
|
||||
"frameworksDesc": "ESP-IDF, Arduino, Rust y Matter",
|
||||
"glossary": "Glosario técnico",
|
||||
"glossaryDesc": "Términos que aparecen en las hojas de datos",
|
||||
"about": "Acerca del proyecto",
|
||||
"aboutDesc": "Autoría, método y código abierto"
|
||||
},
|
||||
"Footer": {
|
||||
"ariaLabel": "Pie de página de ESPDocs",
|
||||
"description": "Documentación independiente del ecosistema ESP32. Datos abiertos, curaduría editorial y enlaces a fuentes oficiales.",
|
||||
"exploreTitle": "Explorar",
|
||||
"toolsTitle": "Herramientas",
|
||||
"projectTitle": "Proyecto",
|
||||
"authorTitle": "Autor",
|
||||
"reportIssue": "Reportar un problema",
|
||||
"repository": "Repositorio",
|
||||
"personalSite": "Sitio personal",
|
||||
"linkedin": "LinkedIn"
|
||||
},
|
||||
"Home": {
|
||||
"badge": "Documentación abierta de ESP32",
|
||||
"titleLine1": "El ESP32,",
|
||||
"titleLine2": " sin ruido.",
|
||||
"lede": "Especificaciones, distribución de pines, comparativas y diagnóstico en una sola lectura. Menos traducción de hojas de datos, más tiempo en el banco de trabajo.",
|
||||
"chooseMyChip": "Elegir mi chip",
|
||||
"exploreSeries": "Explorar las {count} series",
|
||||
"seriesCount": "{count} series",
|
||||
"frameworkCount": "{count} frameworks",
|
||||
"portugueseFlag": "100% en español",
|
||||
"featuredSeries": "Series destacadas",
|
||||
"featuredDesc": "Lo esencial de cada familia antes de abrir la hoja de datos.",
|
||||
"fullIndex": "Índice completo",
|
||||
"toolsTitle": "Comience por el problema.",
|
||||
"toolsEyebrow": "Herramientas",
|
||||
"toolsDesc": "Herramientas para seleccionar el chip adecuado, diagnosticar errores de hardware y acelerar el desarrollo."
|
||||
},
|
||||
"NotFound": {
|
||||
"eyebrow": "Error 404",
|
||||
"title": "Esta página no existe.",
|
||||
"lede": "La URL puede haber cambiado o haber sido escrita incorrectamente. Elija una de estas rutas para continuar.",
|
||||
"backToHome": "Volver al inicio",
|
||||
"seriesTitle": "Series ESP32",
|
||||
"seriesDesc": "12 familias, con distribución de pines y especificaciones.",
|
||||
"selectorTitle": "Selector de chips",
|
||||
"selectorDesc": "Responda ocho preguntas y encuentre los modelos recomendados.",
|
||||
"comparatorTitle": "Comparador",
|
||||
"comparatorDesc": "Hasta cuatro series lado a lado.",
|
||||
"glossaryTitle": "Glosario",
|
||||
"glossaryDesc": "Términos de hardware explicados con claridad."
|
||||
},
|
||||
"Sobre": {
|
||||
"label": "Proyecto independiente",
|
||||
"title": "Acerca de ESPDocs",
|
||||
"lede": "Una plataforma no oficial que organiza información técnica sobre el ESP32 y enlaza directamente a la documentación oficial de Espressif. Creada para la comunidad de hardware abierto.",
|
||||
"viewRepository": "Ver repositorio",
|
||||
"features": {
|
||||
"portugueseTitle": "Contenido seleccionado",
|
||||
"portugueseDesc": "Datos técnicos estructurados y presentados con claridad, sin el ruido de las hojas de datos.",
|
||||
"visualCompareTitle": "Comparaciones visuales",
|
||||
"visualCompareDesc": "Tablas y diagramas para seleccionar la serie adecuada sin abrir diez hojas de datos.",
|
||||
"centralizedAccessTitle": "Acceso centralizado",
|
||||
"centralizedAccessDesc": "Enlaces directos a la documentación oficial, repositorios y ejemplos.",
|
||||
"openSourceTitle": "Código abierto",
|
||||
"openSourceDesc": "Las contribuciones son bienvenidas en Gitea."
|
||||
}
|
||||
},
|
||||
"Series": {
|
||||
"title": "Series ESP32",
|
||||
"description": "12 series de ESP32 lado a lado: ESP32, S2, S3, S31, C2, C3, C5, C6, C61, P4, H2 y H4. Arquitectura, memoria, radio, periféricos y distribución de pines de cada una.",
|
||||
"pinout": "Distribución de pines",
|
||||
"specifications": "Especificaciones",
|
||||
"peripherals": "Periféricos",
|
||||
"architecture": "Arquitectura",
|
||||
"memory": "Memoria",
|
||||
"radio": "Radio",
|
||||
"security": "Seguridad de hardware"
|
||||
},
|
||||
"Catalogo": {
|
||||
"title": "Catálogo de placas de desarrollo",
|
||||
"description": "DevKits oficiales y de terceros con distribución de pines, interfaces y enlaces de compra.",
|
||||
"filterBySeries": "Filtrar por serie",
|
||||
"searchBoards": "Buscar placas..."
|
||||
},
|
||||
"Comparacao": {
|
||||
"title": "Comparador de series ESP32",
|
||||
"description": "Compare hasta 4 series lado a lado con especificaciones completas de procesamiento, radio, memoria y distribución de pines."
|
||||
},
|
||||
"Componentes": {
|
||||
"title": "ESP Component Registry",
|
||||
"description": "Controladores, bibliotecas y manifiestos idf_component.yml listos para usar con ESP-IDF."
|
||||
},
|
||||
"Diagnostico": {
|
||||
"title": "Diagnóstico y solución de problemas",
|
||||
"description": "Brownout, bucles de arranque, pánicos de CPU, FreeRTOS y buenas prácticas de hardware."
|
||||
},
|
||||
"Frameworks": {
|
||||
"title": "Frameworks y SDKs",
|
||||
"description": "Guías y resúmenes de los principales entornos de desarrollo: ESP-IDF, Arduino, MicroPython, Rust y ESP-Matter."
|
||||
},
|
||||
"Glossario": {
|
||||
"title": "Glosario técnico",
|
||||
"description": "Explicaciones prácticas de conceptos de hardware, periféricos, radio y arquitectura presentes en las hojas de datos."
|
||||
},
|
||||
"Seletor": {
|
||||
"title": "Selector inteligente de ESP32",
|
||||
"description": "Responda preguntas objetivas sobre su proyecto y encuentre la serie ideal según criterios técnicos."
|
||||
}
|
||||
}
|
||||
+39
-14
@@ -1,11 +1,10 @@
|
||||
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);
|
||||
|
||||
const SUPPORTED_LOCALES = routing.locales;
|
||||
|
||||
function parseAcceptLanguage(header) {
|
||||
if (!header) return [];
|
||||
return header
|
||||
@@ -37,16 +36,18 @@ function matchLocale(lang) {
|
||||
|
||||
function resolveRootLocale(request) {
|
||||
const cookieValue = request.cookies.get("NEXT_LOCALE")?.value;
|
||||
if (cookieValue && SUPPORTED_LOCALES.includes(cookieValue)) {
|
||||
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) return matched;
|
||||
if (matched && ENABLED_LOCALES.includes(matched)) {
|
||||
return matched;
|
||||
}
|
||||
}
|
||||
return "en";
|
||||
return ENABLED_LOCALES.includes("en") ? "en" : (ENABLED_LOCALES[0] || "pt");
|
||||
}
|
||||
|
||||
export default function middleware(request) {
|
||||
@@ -64,10 +65,10 @@ export default function middleware(request) {
|
||||
return NextResponse.next();
|
||||
}
|
||||
|
||||
// 1. Raiz: negociação de idioma (307)
|
||||
// 1. Raiz: negociação de idioma (307) considerando apenas idiomas ATIVOS
|
||||
if (pathname === "/") {
|
||||
const targetLocale = resolveRootLocale(request);
|
||||
const url = new URL(`/${targetLocale}/`, request.url);
|
||||
const url = new URL(`/${targetLocale}`, request.url);
|
||||
url.search = search;
|
||||
const response = NextResponse.redirect(url, 307);
|
||||
response.headers.set("Vary", "Accept-Language, Cookie");
|
||||
@@ -75,23 +76,47 @@ export default function middleware(request) {
|
||||
return response;
|
||||
}
|
||||
|
||||
// 2. Livro fora do português: 404
|
||||
if (/^\/(en|es|fr|de|zh-CN)\/livro(\/.*)?$/.test(pathname)) {
|
||||
return new NextResponse(null, { status: 404 });
|
||||
// 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. URLs antigas sem prefixo reconhecido: redirecionamento 308 para /pt/<caminho>
|
||||
const hasLocalePrefix = SUPPORTED_LOCALES.some(
|
||||
// 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 (!hasLocalePrefix) {
|
||||
if (!hasActivePrefix) {
|
||||
const url = new URL(`/pt${pathname}`, request.url);
|
||||
url.search = search;
|
||||
return NextResponse.redirect(url, 308);
|
||||
}
|
||||
|
||||
// 4. Delegação para o roteamento do next-intl
|
||||
// 5. Delegação para o roteamento do next-intl para idiomas ativos
|
||||
return intlMiddleware(request);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@ 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",
|
||||
|
||||
Generated
+11
-36
@@ -1285,9 +1285,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1308,9 +1305,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1331,9 +1325,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1354,9 +1345,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1377,9 +1365,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1400,9 +1385,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1582,9 +1564,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1601,9 +1580,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1620,9 +1596,6 @@
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1639,9 +1612,6 @@
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1658,9 +1628,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1677,9 +1644,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6175,6 +6139,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"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",
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <WiFi.h>
|
||||
|
||||
// Substitua pelos dados da sua rede Wi-Fi
|
||||
const char* ssid = "NOME_DA_SUA_REDE";
|
||||
const char* password = "SENHA_DA_SUA_REDE";
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
|
||||
Serial.println("Conectando ao Wi-Fi...");
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
// Aguarda a conexão
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
|
||||
Serial.println("");
|
||||
Serial.println("Wi-Fi conectado com sucesso!");
|
||||
Serial.print("Endereço IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Aqui você pode colocar o código principal do seu programa
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "esp_log.h"
|
||||
#include "audio_pipeline.h"
|
||||
#include "audio_element.h"
|
||||
#include "audio_event_iface.h"
|
||||
#include "audio_common.h"
|
||||
#include "i2s_stream.h"
|
||||
#include "mp3_decoder.h"
|
||||
#include "fatfs_stream.h"
|
||||
#include "esp_peripherals.h"
|
||||
#include "periph_sdcard.h"
|
||||
|
||||
static const char *TAG = "HELLO_ADF";
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Inicializa periféricos (como o SD card)
|
||||
esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG();
|
||||
esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg);
|
||||
periph_sdcard_cfg_t sd_cfg = {
|
||||
.root = "/sdcard",
|
||||
};
|
||||
esp_periph_handle_t sdcard_handle = periph_sdcard_init(&sd_cfg);
|
||||
esp_periph_start(set, sdcard_handle);
|
||||
|
||||
// Espera o SD card montar
|
||||
periph_sdcard_wait_for_ready(sdcard_handle, portMAX_DELAY);
|
||||
|
||||
ESP_LOGI(TAG, "SD card montado!");
|
||||
|
||||
// Cria o pipeline
|
||||
audio_pipeline_handle_t pipeline;
|
||||
audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
|
||||
pipeline = audio_pipeline_init(&pipeline_cfg);
|
||||
|
||||
// Elementos: arquivo (fatfs), decodificador (mp3) e saída (i2s)
|
||||
audio_element_handle_t fatfs_stream_reader, i2s_stream_writer, mp3_decoder;
|
||||
|
||||
fatfs_stream_cfg_t fatfs_cfg = FATFS_STREAM_CFG_DEFAULT();
|
||||
fatfs_cfg.type = AUDIO_STREAM_READER;
|
||||
fatfs_stream_reader = fatfs_stream_init(&fatfs_cfg);
|
||||
|
||||
mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG();
|
||||
mp3_decoder = mp3_decoder_init(&mp3_cfg);
|
||||
|
||||
i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT();
|
||||
i2s_cfg.type = AUDIO_STREAM_WRITER;
|
||||
i2s_stream_writer = i2s_stream_init(&i2s_cfg);
|
||||
|
||||
// Registra e conecta elementos
|
||||
audio_pipeline_register(pipeline, fatfs_stream_reader, "file");
|
||||
audio_pipeline_register(pipeline, mp3_decoder, "mp3");
|
||||
audio_pipeline_register(pipeline, i2s_stream_writer, "i2s");
|
||||
|
||||
audio_pipeline_link(pipeline, (const char *[]) {"file", "mp3", "i2s"}, 3);
|
||||
|
||||
// Define o arquivo MP3 a ser tocado
|
||||
audio_element_set_uri(fatfs_stream_reader, "/sdcard/test.mp3");
|
||||
|
||||
// Inicia o pipeline
|
||||
ESP_LOGI(TAG, "Iniciando pipeline...");
|
||||
audio_pipeline_run(pipeline);
|
||||
|
||||
// Mantém o pipeline rodando
|
||||
while (1) {
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
// (Nunca chega aqui, mas seria o cleanup)
|
||||
audio_pipeline_stop(pipeline);
|
||||
audio_pipeline_wait_for_stop(pipeline);
|
||||
audio_pipeline_terminate(pipeline);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <stdio.h>
|
||||
#include "esp_dsp.h"
|
||||
|
||||
#define N 8 // Tamanho do vetor
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Vetor de entrada (exemplo de sinal)
|
||||
float x[N] = {1.0, -2.0, 3.0, -4.0, 2.5, -1.5, 0.0, 4.5};
|
||||
float y[N]; // Vetor de saída
|
||||
|
||||
// Inicializa o ESP-DSP
|
||||
esp_err_t ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
printf("Erro ao inicializar o ESP-DSP!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Sinal de entrada:\n");
|
||||
for (int i = 0; i < N; i++) {
|
||||
printf("%f ", x[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Calcula o quadrado de cada valor
|
||||
dsps_mulc_f32(x, y, N, 1.0f);
|
||||
dsps_mul_f32(y, y, y, N, 1, 1, 1);
|
||||
|
||||
// Soma todos os quadrados
|
||||
float soma = 0;
|
||||
dsps_sum_f32(y, N, &soma, 1);
|
||||
|
||||
// Calcula a magnitude (raiz da soma dos quadrados)
|
||||
float magnitude = sqrtf(soma);
|
||||
|
||||
printf("Magnitude do vetor: %f\n", magnitude);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* ESP-IDF v5.x+ Example for ESP32
|
||||
* Demonstration of system initialization, FreeRTOS task management and unified logging
|
||||
*
|
||||
* Component management (main/idf_component.yml):
|
||||
* dependencies:
|
||||
* espressif/led_strip: "^2.5.0"
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_chip_info.h"
|
||||
|
||||
static const char *TAG = "main_app";
|
||||
|
||||
#define BLINK_GPIO GPIO_NUM_2 // Adjust according to your board's LED pin
|
||||
|
||||
static void blink_task(void *pvParameters)
|
||||
{
|
||||
// Configure the GPIO pin using the modern ESP-IDF API
|
||||
gpio_reset_pin(BLINK_GPIO);
|
||||
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
|
||||
|
||||
bool led_state = false;
|
||||
|
||||
while (1) {
|
||||
led_state = !led_state;
|
||||
gpio_set_level(BLINK_GPIO, led_state);
|
||||
|
||||
ESP_LOGI(TAG, "LED %s | Free heap: %lu bytes",
|
||||
led_state ? "LIGADO" : "DESLIGADO",
|
||||
(unsigned long)esp_get_free_heap_size());
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Informações do chip SoC
|
||||
esp_chip_info_t chip_info;
|
||||
esp_chip_info(&chip_info);
|
||||
|
||||
ESP_LOGI(TAG, "===========================================");
|
||||
ESP_LOGI(TAG, " Iniciando ESP-IDF v5.x Modern Application ");
|
||||
ESP_LOGI(TAG, " Modelo do Chip: %d | Núcleos: %d | Rev: %d",
|
||||
chip_info.model, chip_info.cores, chip_info.revision);
|
||||
ESP_LOGI(TAG, "===========================================");
|
||||
|
||||
// Cria uma tarefa FreeRTOS dedicada
|
||||
xTaskCreate(blink_task, "blink_task", 3072, NULL, 5, NULL);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* ESP-IoT-Solution Example para ESP32
|
||||
* Initialization de Botão Inteligente com Callbacks e Driver de Display/Sensores
|
||||
*
|
||||
* Dependência (idf_component.yml):
|
||||
* espressif/button: "^3.3.0"
|
||||
* espressif/led_indicator: "^1.2.0"
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "iot_button.h"
|
||||
#include "led_indicator.h"
|
||||
|
||||
static const char *TAG = "iot_solution_app";
|
||||
|
||||
#define BUTTON_GPIO_NUM 0 // Botão BOOT nativo
|
||||
#define LED_INDICATOR_GPIO 2 // LED indicador
|
||||
|
||||
static led_indicator_handle_t led_handle = NULL;
|
||||
|
||||
/* Callback para clique único do botão */
|
||||
static void button_single_click_cb(void *arg, void *data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Evento: Clique Único detectado!");
|
||||
led_indicator_start(led_handle, BLINK_DOUBLE_FAST);
|
||||
}
|
||||
|
||||
/* Callback para clique longo (> 3 segundos) */
|
||||
static void button_long_press_cb(void *arg, void *data)
|
||||
{
|
||||
ESP_LOGW(TAG, "Evento: Pressionamento Longo! Acionando modo de reset de fábrica.");
|
||||
led_indicator_start(led_handle, BLINK_BREATHE_FAST);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Iniciando ESP-IoT-Solution Component Suite");
|
||||
|
||||
// 1. Configuration do LED Indicator
|
||||
led_indicator_gpio_config_t led_cfg = {
|
||||
.is_active_level_high = true,
|
||||
.gpio_num = LED_INDICATOR_GPIO,
|
||||
};
|
||||
led_handle = led_indicator_create(&led_cfg);
|
||||
|
||||
// 2. Configuration do Botão com debounce de hardware/software automático
|
||||
button_config_t btn_cfg = {
|
||||
.type = BUTTON_TYPE_GPIO,
|
||||
.long_press_time = 3000,
|
||||
.short_press_time = 180,
|
||||
.gpio_button_config = {
|
||||
.gpio_num = BUTTON_GPIO_NUM,
|
||||
.active_level = 0,
|
||||
},
|
||||
};
|
||||
|
||||
button_handle_t btn_handle = iot_button_create(&btn_cfg);
|
||||
assert(btn_handle != NULL);
|
||||
|
||||
// Registra callbacks para diferentes gestos
|
||||
iot_button_register_cb(btn_handle, BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
|
||||
iot_button_register_cb(btn_handle, BUTTON_LONG_PRESS_START, button_long_press_cb, NULL);
|
||||
|
||||
ESP_LOGI(TAG, "Drivers inicializados com sucesso! Pressione o botão GPIO 0.");
|
||||
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <stdio.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_matter.h"
|
||||
#include "esp_matter_controller.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
static const char *TAG = "esp-matter-example";
|
||||
|
||||
void app_event_cb(const esp_matter_event_t *event)
|
||||
{
|
||||
switch (event->event_id) {
|
||||
case ESP_MATTER_EVENT_ATTRIBUTE_UPDATE: {
|
||||
const esp_matter_attr_update_t *attr_update = &event->data.attr_update;
|
||||
if (attr_update->endpoint_id == 1 && attr_update->cluster_id == ESP_MATTER_ON_OFF_CLUSTER_ID) {
|
||||
bool on = false;
|
||||
esp_matter_attribute_get(attr_update->endpoint_id, attr_update->cluster_id,
|
||||
attr_update->attribute_id, &on);
|
||||
ESP_LOGI(TAG, "Lâmpada %s", on ? "ligada" : "desligada");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Inicializa NVS
|
||||
esp_err_t err = nvs_flash_init();
|
||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
}
|
||||
|
||||
// Inicializa o Matter node
|
||||
esp_matter::node_t *node = esp_matter::node::create(NULL, app_event_cb);
|
||||
esp_matter::endpoint_t *endpoint = esp_matter::endpoint::create(node, ESP_MATTER_ENDPOINT_TYPE_ON_OFF_LIGHT);
|
||||
|
||||
// Inicia o stack Matter
|
||||
ESP_ERROR_CHECK(esp_matter::start(node));
|
||||
|
||||
ESP_LOGI(TAG, "Dispositivo Matter iniciado. Aguardando comissionamento...");
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <stdio.h>
|
||||
#include "esp_nn.h"
|
||||
#include "esp_nn_defs.h"
|
||||
|
||||
#define INPUT_SIZE 4
|
||||
#define OUTPUT_SIZE 3
|
||||
|
||||
void print_array(const char *label, int16_t *array, int size) {
|
||||
printf("%s: ", label);
|
||||
for (int i = 0; i < size; i++) {
|
||||
printf("%d ", array[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Vetor de entrada (ex: saída de uma camada anterior)
|
||||
int16_t input[INPUT_SIZE] = {1, 2, 3, 4};
|
||||
|
||||
// Pesos da camada densa (3x4)
|
||||
int8_t weights[OUTPUT_SIZE * INPUT_SIZE] = {
|
||||
1, -1, 2, 0,
|
||||
0, 1, -1, 1,
|
||||
2, 0, 1, -2
|
||||
};
|
||||
|
||||
// Bias de cada neurônio
|
||||
int16_t bias[OUTPUT_SIZE] = {10, -5, 0};
|
||||
|
||||
// Saída
|
||||
int16_t output[OUTPUT_SIZE];
|
||||
|
||||
// Multiplicação da matriz: output = weights * input + bias
|
||||
esp_nn_mul_mat_16x8_16(weights, input, bias, output,
|
||||
OUTPUT_SIZE, INPUT_SIZE, /*shift=*/0);
|
||||
|
||||
print_array("Antes da ReLU", output, OUTPUT_SIZE);
|
||||
|
||||
// Aplicar função de ativação ReLU
|
||||
esp_nn_relu_16(output, OUTPUT_SIZE);
|
||||
|
||||
print_array("Depois da ReLU", output, OUTPUT_SIZE);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* ESP-NOW Example para ESP32
|
||||
* Comunicação Sem Fio Ponto-a-Ponto e Broadcast sem roteador Wi-Fi
|
||||
*
|
||||
* Protocolo nativo integrado no ESP-IDF
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_now.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
static const char *TAG = "esp_now_demo";
|
||||
|
||||
// Estrutura de dados enviada no pacote
|
||||
typedef struct {
|
||||
uint32_t sensor_id;
|
||||
float temperatura;
|
||||
float umidade;
|
||||
uint32_t tempo_ms;
|
||||
} __attribute__((packed)) dados_pacote_t;
|
||||
|
||||
// Endereço MAC de Broadcast (envia para todos os nós ESP-NOW por perto)
|
||||
static const uint8_t broadcast_mac[ESP_NOW_ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
|
||||
/* Callback executado ao enviar um pacote */
|
||||
static void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status)
|
||||
{
|
||||
ESP_LOGI(TAG, "Envio concluído: %s", status == ESP_NOW_SEND_SUCCESS ? "SUCESSO (ACK)" : "FALHA");
|
||||
}
|
||||
|
||||
/* Callback executado ao receber um pacote de outro ESP32 */
|
||||
static void on_data_recv(const esp_now_recv_info_t *recv_info, const uint8_t *data, int len)
|
||||
{
|
||||
if (len == sizeof(dados_pacote_t)) {
|
||||
dados_pacote_t *pct = (dados_pacote_t *)data;
|
||||
ESP_LOGI(TAG, "Pacote recebido de [%02X:%02X:%02X:%02X:%02X:%02X]: Sensor #%ld | Temp: %.1f C | Umid: %.1f %%",
|
||||
recv_info->src_addr[0], recv_info->src_addr[1], recv_info->src_addr[2],
|
||||
recv_info->src_addr[3], recv_info->src_addr[4], recv_info->src_addr[5],
|
||||
pct->sensor_id, pct->temperatura, pct->umidade);
|
||||
}
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Inicializa NVS e Wi-Fi em modo Station
|
||||
nvs_flash_init();
|
||||
esp_netif_init();
|
||||
esp_event_loop_create_default();
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
esp_wifi_init(&cfg);
|
||||
esp_wifi_set_mode(WIFI_MODE_STA);
|
||||
esp_wifi_start();
|
||||
|
||||
// Inicializa o protocolo ESP-NOW
|
||||
ESP_ERROR_CHECK(esp_now_init());
|
||||
esp_now_register_send_cb(on_data_sent);
|
||||
esp_now_register_recv_cb(on_data_recv);
|
||||
|
||||
// Registra o peer de Broadcast
|
||||
esp_now_peer_info_t peer_info = {
|
||||
.channel = 1,
|
||||
.ifidx = WIFI_IF_STA,
|
||||
.encrypt = false,
|
||||
};
|
||||
memcpy(peer_info.peer_addr, broadcast_mac, ESP_NOW_ETH_ALEN);
|
||||
ESP_ERROR_CHECK(esp_now_add_peer(&peer_info));
|
||||
|
||||
ESP_LOGI(TAG, "ESP-NOW pronto! Enviando telemetria a cada 3 segundos...");
|
||||
|
||||
dados_pacote_t telemetria = {
|
||||
.sensor_id = 101,
|
||||
.temperatura = 24.8f,
|
||||
.umidade = 58.2f,
|
||||
};
|
||||
|
||||
while (1) {
|
||||
telemetria.tempo_ms = esp_log_timestamp();
|
||||
telemetria.temperatura += ((float)(rand() % 10) - 5.0f) / 10.0f;
|
||||
|
||||
esp_err_t res = esp_now_send(broadcast_mac, (uint8_t *)&telemetria, sizeof(telemetria));
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Erro ao disparar envio ESP-NOW: %d", res);
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(3000));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* ESP-RainMaker Example para ESP32
|
||||
* Dispositivo: Interruptor Inteligente com controle via App e Nuvem
|
||||
*
|
||||
* Dependência (idf_component.yml):
|
||||
* espressif/esp_rainmaker: "^1.4.0"
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
#include <esp_rmaker_core.h>
|
||||
#include <esp_rmaker_standard_params.h>
|
||||
#include <esp_rmaker_standard_devices.h>
|
||||
#include <app_wifi.h>
|
||||
|
||||
static const char *TAG = "app_rainmaker";
|
||||
static esp_rmaker_device_t *switch_device;
|
||||
|
||||
/* Callback acionado quando o usuário altera o estado no App móvel */
|
||||
static esp_err_t write_cb(const esp_rmaker_device_t *dev, const esp_rmaker_param_val_t val, void *priv_data, esp_rmaker_write_ctx_t *ctx)
|
||||
{
|
||||
if (ctx) {
|
||||
ESP_LOGI(TAG, "Comando recebido via %s", esp_rmaker_device_cb_src_to_str(ctx->src));
|
||||
}
|
||||
|
||||
bool state = val.val.b;
|
||||
ESP_LOGI(TAG, "Estado do interruptor alterado para: %s", state ? "LIGADO" : "DESLIGADO");
|
||||
|
||||
// Atualiza o parâmetro na nuvem e no aplicativo
|
||||
esp_rmaker_param_update_and_report(priv_data, val);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Initialization da memória não-volátil (NVS)
|
||||
esp_err_t err = nvs_flash_init();
|
||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
err = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK(err);
|
||||
|
||||
// Inicializa o provisionamento Wi-Fi
|
||||
app_wifi_init();
|
||||
|
||||
// Configura o nó RainMaker
|
||||
esp_rmaker_config_t rainmaker_cfg = {
|
||||
.enable_time_sync = true,
|
||||
};
|
||||
esp_rmaker_node_t *node = esp_rmaker_node_init(&rainmaker_cfg, "ESP32_SmartSwitch", "Switch");
|
||||
|
||||
// Cria o dispositivo padrão 'Switch'
|
||||
switch_device = esp_rmaker_switch_device_create("Luz Sala", NULL, true);
|
||||
|
||||
// Registra callback de escrita
|
||||
esp_rmaker_device_add_cb(switch_device, write_cb, NULL);
|
||||
esp_rmaker_node_add_device(node, switch_device);
|
||||
|
||||
// Habilita serviços adicionais (OTA e Timezone)
|
||||
esp_rmaker_ota_enable_default();
|
||||
esp_rmaker_timezone_service_enable();
|
||||
|
||||
// Inicia o agente RainMaker
|
||||
esp_rmaker_start();
|
||||
|
||||
// Inicia o provisionamento Wi-Fi via BLE (abre no app oficial RainMaker)
|
||||
app_wifi_start(POP_TYPE_RANDOM);
|
||||
|
||||
ESP_LOGI(TAG, "Nó RainMaker pronto! Escaneie o QR Code no app ESP RainMaker.");
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* ESP-SR Example para ESP32-S3 / ESP32-P4
|
||||
* Reconhecimento de Fala Local Offline (WakeNet + MultiNet)
|
||||
*
|
||||
* Dependência (idf_component.yml):
|
||||
* espressif/esp-sr: "^1.5.0"
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_wn_iface.h"
|
||||
#include "esp_wn_models.h"
|
||||
#include "esp_mn_iface.h"
|
||||
#include "esp_mn_models.h"
|
||||
#include "esp_afe_sr_iface.h"
|
||||
#include "esp_afe_sr_models.h"
|
||||
|
||||
static const char *TAG = "app_voice_sr";
|
||||
|
||||
void feed_audio_task(void *arg)
|
||||
{
|
||||
esp_afe_sr_data_t *afe_data = (esp_afe_sr_data_t *)arg;
|
||||
int audio_chunksize = afe_handle->get_feed_chunksize(afe_data);
|
||||
int16_t *feed_buff = (int16_t *)malloc(audio_chunksize * sizeof(int16_t) * 2);
|
||||
|
||||
while (1) {
|
||||
// Leitura de áudio I2S dos microfones da placa
|
||||
// i2s_read(I2S_NUM_0, feed_buff, ...);
|
||||
|
||||
afe_handle->feed(afe_data, feed_buff);
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
free(feed_buff);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void speech_recognition_task(void *arg)
|
||||
{
|
||||
esp_afe_sr_data_t *afe_data = (esp_afe_sr_data_t *)arg;
|
||||
const esp_afe_sr_iface_t *afe_handle = &ESP_AFE_SR_HANDLE;
|
||||
|
||||
// Inicializa o modelo de comandos de fala (MultiNet)
|
||||
const esp_mn_iface_t *multinet = &ESP_MN_HANDLE;
|
||||
model_iface_data_t *model_data = multinet->create(&MULTINET_MODEL, 6000);
|
||||
|
||||
ESP_LOGI(TAG, "Aguardando palavra-chave de ativação (ex: 'Hi, ESP')...");
|
||||
|
||||
while (1) {
|
||||
afe_fetch_result_t *res = afe_handle->fetch(afe_data);
|
||||
if (!res || res->ret_value == ESP_FAIL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 1. Verificação de Wake Word (Palavra de ativação)
|
||||
if (res->wake_word_detected == WAKENET_DETECTED) {
|
||||
ESP_LOGW(TAG, ">>> PALAVRA-CHAVE DETECTADA! Canal de escuta aberto.");
|
||||
}
|
||||
|
||||
// 2. Reconhecimento de comando local
|
||||
if (res->raw_data_size > 0) {
|
||||
esp_mn_state_t mn_state = multinet->detect(model_data, res->data);
|
||||
|
||||
if (mn_state == ESP_MN_STATE_DETECTED) {
|
||||
esp_mn_results_t *mn_res = multinet->get_results(model_data);
|
||||
ESP_LOGI(TAG, ">>> COMANDO RECONHECIDO: ID #%d (Frase correspondente)", mn_res->command_id[0]);
|
||||
|
||||
// Exemplo de ação
|
||||
if (mn_res->command_id[0] == 1) {
|
||||
ESP_LOGI(TAG, "Ação: Ligar Luz da Sala");
|
||||
} else if (mn_res->command_id[0] == 2) {
|
||||
ESP_LOGI(TAG, "Ação: Desligar Luz da Sala");
|
||||
}
|
||||
} else if (mn_state == ESP_MN_STATE_TIMEOUT) {
|
||||
ESP_LOGI(TAG, "Tempo esgotado. Retornando ao modo de escuta de Wake Word.");
|
||||
}
|
||||
}
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Iniciando ESP-SR Speech Recognition Engine");
|
||||
|
||||
// Configura o pipeline de Audio Front-End (AEC, BSS, VAD, WakeNet)
|
||||
afe_config_t afe_config = AFE_CONFIG_DEFAULT();
|
||||
afe_config.wakenet_init = true;
|
||||
afe_config.voice_communication_init = false;
|
||||
|
||||
esp_afe_sr_data_t *afe_data = ESP_AFE_SR_HANDLE.create_from_config(&afe_config);
|
||||
|
||||
// Cria as tarefas de alimentação de áudio e reconhecimento
|
||||
xTaskCreatePinnedToCore(feed_audio_task, "feed_task", 4096, afe_data, 5, NULL, 0);
|
||||
xTaskCreatePinnedToCore(speech_recognition_task, "sr_task", 8192, afe_data, 5, NULL, 1);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#include "esp_camera.h"
|
||||
#include "fd_forward.h" // Face Detection
|
||||
#include "fr_forward.h" // Face Recognition
|
||||
#include "human_face_detect_msr01.hpp"
|
||||
#include "human_face_detect_mnp01.hpp"
|
||||
|
||||
#define CAMERA_MODEL_AI_THINKER // ou o modelo da sua placa
|
||||
|
||||
#include "camera_pins.h"
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
Serial.println("Iniciando câmera...");
|
||||
|
||||
camera_config_t config;
|
||||
config.ledc_channel = LEDC_CHANNEL_0;
|
||||
config.ledc_timer = LEDC_TIMER_0;
|
||||
config.pin_d0 = Y2_GPIO_NUM;
|
||||
config.pin_d1 = Y3_GPIO_NUM;
|
||||
config.pin_d2 = Y4_GPIO_NUM;
|
||||
config.pin_d3 = Y5_GPIO_NUM;
|
||||
config.pin_d4 = Y6_GPIO_NUM;
|
||||
config.pin_d5 = Y7_GPIO_NUM;
|
||||
config.pin_d6 = Y8_GPIO_NUM;
|
||||
config.pin_d7 = Y9_GPIO_NUM;
|
||||
config.pin_xclk = XCLK_GPIO_NUM;
|
||||
config.pin_pclk = PCLK_GPIO_NUM;
|
||||
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||
config.pin_href = HREF_GPIO_NUM;
|
||||
config.pin_sscb_sda = SIOD_GPIO_NUM;
|
||||
config.pin_sscb_scl = SIOC_GPIO_NUM;
|
||||
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||
config.pin_reset = RESET_GPIO_NUM;
|
||||
config.xclk_freq_hz = 20000000;
|
||||
config.pixel_format = PIXFORMAT_RGB565;
|
||||
config.frame_size = FRAMESIZE_QVGA;
|
||||
config.fb_count = 1;
|
||||
|
||||
if (esp_camera_init(&config) != ESP_OK) {
|
||||
Serial.println("Falha ao iniciar a câmera!");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.println("Câmera inicializada com sucesso!");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
camera_fb_t *fb = esp_camera_fb_get();
|
||||
if (!fb) {
|
||||
Serial.println("Falha ao capturar imagem!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Detecta rostos na imagem
|
||||
box_array_t *faces = face_detect_msr01(fb->buf, fb->width, fb->height, fb->format);
|
||||
if (faces) {
|
||||
Serial.printf("Rostos detectados: %d\n", faces->len);
|
||||
for (int i = 0; i < faces->len; i++) {
|
||||
box_t *box = &faces->box[i];
|
||||
Serial.printf("Face %d - x:%d y:%d w:%d h:%d\n", i, box->box_p[0], box->box_p[1],
|
||||
box->box_p[2] - box->box_p[0], box->box_p[3] - box->box_p[1]);
|
||||
}
|
||||
dl_lib_free(faces);
|
||||
} else {
|
||||
Serial.println("Nenhum rosto detectado.");
|
||||
}
|
||||
|
||||
esp_camera_fb_return(fb);
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* ESP-Zigbee-SDK Example para ESP32-H2 e ESP32-C6 (IEEE 802.15.4)
|
||||
* Dispositivo: Lâmpada Inteligente Zigbee 3.0 (Home Automation End Device)
|
||||
*
|
||||
* Dependência (idf_component.yml):
|
||||
* espressif/esp-zigbee-lib: "^1.6.0"
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_zigbee_core.h"
|
||||
|
||||
static const char *TAG = "zigbee_light_device";
|
||||
|
||||
#define HA_ESP_LIGHT_ENDPOINT 1
|
||||
#define ESP_ZB_PRIMARY_CHANNEL_MASK (1l << 15) // Canal 15 padrão Zigbee
|
||||
|
||||
/* Callback de escrita em atributos Zigbee (ex: Liga/Desliga via Home Assistant) */
|
||||
static esp_err_t zb_attribute_handler(const esp_zb_zcl_set_attr_value_message_t *message)
|
||||
{
|
||||
if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_ON_OFF) {
|
||||
if (message->attribute.id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID &&
|
||||
message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_BOOL) {
|
||||
bool on_off_state = message->attribute.data.value ? *(bool *)message->attribute.data.value : false;
|
||||
ESP_LOGW(TAG, ">>> COMANDO ZIGBEE RECEBIDO: Lâmpada %s", on_off_state ? "LIGADA" : "DESLIGADA");
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Callback de eventos da pilha Zigbee */
|
||||
void esp_zb_app_signal_handler(esp_zb_app_signal_msg_t *signal_msg)
|
||||
{
|
||||
uint32_t *p_sg_p = signal_msg->p_app_signal;
|
||||
esp_err_t err_status = signal_msg->esp_err_status;
|
||||
esp_zb_app_signal_type_t sig_type = *p_sg_p;
|
||||
|
||||
switch (sig_type) {
|
||||
case ESP_ZB_ZDO_SIGNAL_SKIP_STARTUP:
|
||||
ESP_LOGI(TAG, "Iniciando comissionamento na rede Zigbee...");
|
||||
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
|
||||
break;
|
||||
case ESP_ZB_BDB_SIGNAL_STEERING:
|
||||
if (err_status == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Conectado com sucesso à rede Zigbee 3.0!");
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Buscando coordenador Zigbee novamente...");
|
||||
esp_zb_scheduler_alarm((esp_zb_callback_t)esp_zb_bdb_start_top_level_commissioning, ESP_ZB_BDB_MODE_NETWORK_STEERING, 1000);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void esp_zb_task(void *pvParameters)
|
||||
{
|
||||
// Configura nó Zigbee como End Device
|
||||
esp_zb_cfg_t zb_nwk_cfg = {
|
||||
.esp_zb_role = ESP_ZB_DEVICE_TYPE_ED,
|
||||
.install_code_policy = false,
|
||||
.nwk_cfg.zed_cfg = {
|
||||
.ed_timeout = ESP_ZB_ED_0_5_MIN,
|
||||
.keep_alive = 3000,
|
||||
},
|
||||
};
|
||||
esp_zb_init(&zb_nwk_cfg);
|
||||
|
||||
// Cria o cluster de On/Off de iluminação residencial
|
||||
esp_zb_on_off_light_cfg_t light_cfg = ESP_ZB_DEFAULT_ON_OFF_LIGHT_CONFIG();
|
||||
esp_zb_ep_list_t *ep_list = esp_zb_on_off_light_ep_create(HA_ESP_LIGHT_ENDPOINT, &light_cfg);
|
||||
|
||||
// Registra endpoint e manipulador de atributos
|
||||
esp_zb_device_register(ep_list);
|
||||
esp_zb_core_action_handler_register(zb_attribute_handler);
|
||||
|
||||
esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK);
|
||||
ESP_ERROR_CHECK(esp_zb_start(false));
|
||||
esp_zb_main_loop_iteration();
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
|
||||
// Inicializa a pilha de rádio IEEE 802.15.4
|
||||
esp_zb_platform_config_t config = {
|
||||
.radio_config = { .radio_mode = ZB_RADIO_MODE_NATIVE },
|
||||
.host_config = { .host_connection_mode = ZB_HOST_CONNECTION_MODE_NONE },
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_zb_platform_config(&config));
|
||||
|
||||
xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
from machine import Pin
|
||||
from time import sleep
|
||||
|
||||
# Define o pino 2 como saída (geralmente o LED embutido)
|
||||
led = Pin(2, Pin.OUT)
|
||||
|
||||
while True:
|
||||
led.value(1) # Liga o LED
|
||||
sleep(0.5) # Aguarda 0,5 segundos
|
||||
led.value(0) # Desliga o LED
|
||||
sleep(0.5) # Aguarda 0,5 segundos
|
||||
@@ -0,0 +1,48 @@
|
||||
//! Exemplo Rust no ESP32 usando `esp-hal` (Modo Bare-Metal / no_std)
|
||||
//! Pisca um LED e envia mensagens via UART Serial com segurança de memória garantida.
|
||||
//!
|
||||
//! Cargo.toml:
|
||||
//! esp-hal = { version = "0.22", features = ["esp32s3"] }
|
||||
//! esp-println = { version = "0.12", features = ["esp32s3", "log"] }
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
gpio::{Io, Level, Output},
|
||||
peripherals::Peripherals,
|
||||
system::SystemControl,
|
||||
timer::timg::TimerGroup,
|
||||
delay::Delay,
|
||||
prelude::*,
|
||||
};
|
||||
use esp_println::println;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
// Inicializa periféricos do SoC com verificação em tempo de compilação
|
||||
let peripherals = Peripherals::take();
|
||||
let system = SystemControl::new(peripherals.SYSTEM);
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
// Configura os pinos de E/S
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let mut led = Output::new(io.pins.gpio2, Level::Low);
|
||||
|
||||
let delay = Delay::new(&clocks);
|
||||
|
||||
println!("🦀 Firmware Rust Bare-Metal inicializado no ESP32!");
|
||||
|
||||
let mut counter: u32 = 0;
|
||||
|
||||
loop {
|
||||
// Inverte estado do LED com garantia de exclusão mútua
|
||||
led.toggle();
|
||||
counter += 1;
|
||||
|
||||
println!("Ciclo Rust #{}: LED está {:?}", counter, led.is_set_high());
|
||||
delay.delay_millis(500);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <WiFi.h>
|
||||
|
||||
// Substitua pelos dados da sua rede Wi-Fi
|
||||
const char* ssid = "NOME_DA_SUA_REDE";
|
||||
const char* password = "SENHA_DA_SUA_REDE";
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
|
||||
Serial.println("Conectando ao Wi-Fi...");
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
// Aguarda a conexão
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
|
||||
Serial.println("");
|
||||
Serial.println("Wi-Fi conectado com sucesso!");
|
||||
Serial.print("Endereço IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Aqui você pode colocar o código principal do seu programa
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "esp_log.h"
|
||||
#include "audio_pipeline.h"
|
||||
#include "audio_element.h"
|
||||
#include "audio_event_iface.h"
|
||||
#include "audio_common.h"
|
||||
#include "i2s_stream.h"
|
||||
#include "mp3_decoder.h"
|
||||
#include "fatfs_stream.h"
|
||||
#include "esp_peripherals.h"
|
||||
#include "periph_sdcard.h"
|
||||
|
||||
static const char *TAG = "HELLO_ADF";
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Inicializa periféricos (como o SD card)
|
||||
esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG();
|
||||
esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg);
|
||||
periph_sdcard_cfg_t sd_cfg = {
|
||||
.root = "/sdcard",
|
||||
};
|
||||
esp_periph_handle_t sdcard_handle = periph_sdcard_init(&sd_cfg);
|
||||
esp_periph_start(set, sdcard_handle);
|
||||
|
||||
// Espera o SD card montar
|
||||
periph_sdcard_wait_for_ready(sdcard_handle, portMAX_DELAY);
|
||||
|
||||
ESP_LOGI(TAG, "SD card montado!");
|
||||
|
||||
// Cria o pipeline
|
||||
audio_pipeline_handle_t pipeline;
|
||||
audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG();
|
||||
pipeline = audio_pipeline_init(&pipeline_cfg);
|
||||
|
||||
// Elementos: arquivo (fatfs), decodificador (mp3) e saída (i2s)
|
||||
audio_element_handle_t fatfs_stream_reader, i2s_stream_writer, mp3_decoder;
|
||||
|
||||
fatfs_stream_cfg_t fatfs_cfg = FATFS_STREAM_CFG_DEFAULT();
|
||||
fatfs_cfg.type = AUDIO_STREAM_READER;
|
||||
fatfs_stream_reader = fatfs_stream_init(&fatfs_cfg);
|
||||
|
||||
mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG();
|
||||
mp3_decoder = mp3_decoder_init(&mp3_cfg);
|
||||
|
||||
i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT();
|
||||
i2s_cfg.type = AUDIO_STREAM_WRITER;
|
||||
i2s_stream_writer = i2s_stream_init(&i2s_cfg);
|
||||
|
||||
// Registra e conecta elementos
|
||||
audio_pipeline_register(pipeline, fatfs_stream_reader, "file");
|
||||
audio_pipeline_register(pipeline, mp3_decoder, "mp3");
|
||||
audio_pipeline_register(pipeline, i2s_stream_writer, "i2s");
|
||||
|
||||
audio_pipeline_link(pipeline, (const char *[]) {"file", "mp3", "i2s"}, 3);
|
||||
|
||||
// Define o arquivo MP3 a ser tocado
|
||||
audio_element_set_uri(fatfs_stream_reader, "/sdcard/test.mp3");
|
||||
|
||||
// Inicia el pipeline
|
||||
ESP_LOGI(TAG, "Iniciando pipeline...");
|
||||
audio_pipeline_run(pipeline);
|
||||
|
||||
// Mantém o pipeline rodando
|
||||
while (1) {
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
// (Nunca chega aqui, mas seria o cleanup)
|
||||
audio_pipeline_stop(pipeline);
|
||||
audio_pipeline_wait_for_stop(pipeline);
|
||||
audio_pipeline_terminate(pipeline);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <stdio.h>
|
||||
#include "esp_dsp.h"
|
||||
|
||||
#define N 8 // Tamanho do vetor
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Vetor de entrada (exemplo de sinal)
|
||||
float x[N] = {1.0, -2.0, 3.0, -4.0, 2.5, -1.5, 0.0, 4.5};
|
||||
float y[N]; // Vetor de saída
|
||||
|
||||
// Inicializa o ESP-DSP
|
||||
esp_err_t ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
printf("Erro ao inicializar o ESP-DSP!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Sinal de entrada:\n");
|
||||
for (int i = 0; i < N; i++) {
|
||||
printf("%f ", x[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Calcula o quadrado de cada valor
|
||||
dsps_mulc_f32(x, y, N, 1.0f);
|
||||
dsps_mul_f32(y, y, y, N, 1, 1, 1);
|
||||
|
||||
// Soma todos os quadrados
|
||||
float soma = 0;
|
||||
dsps_sum_f32(y, N, &soma, 1);
|
||||
|
||||
// Calcula a magnitude (raiz da soma dos quadrados)
|
||||
float magnitude = sqrtf(soma);
|
||||
|
||||
printf("Magnitude do vetor: %f\n", magnitude);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Ejemplo ESP-IDF v5.x+ para ESP32
|
||||
* Demostración de inicialización del sistema, gestión de tareas FreeRTOS y log unificado
|
||||
*
|
||||
* Gestión de componentes (main/idf_component.yml):
|
||||
* dependencies:
|
||||
* espressif/led_strip: "^2.5.0"
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_chip_info.h"
|
||||
|
||||
static const char *TAG = "main_app";
|
||||
|
||||
#define BLINK_GPIO GPIO_NUM_2 // Ajuste según el pin del LED de su placa
|
||||
|
||||
static void blink_task(void *pvParameters)
|
||||
{
|
||||
// Configura el pin GPIO con la nueva API de ESP-IDF
|
||||
gpio_reset_pin(BLINK_GPIO);
|
||||
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
|
||||
|
||||
bool led_state = false;
|
||||
|
||||
while (1) {
|
||||
led_state = !led_state;
|
||||
gpio_set_level(BLINK_GPIO, led_state);
|
||||
|
||||
ESP_LOGI(TAG, "LED %s | Heap libre: %lu bytes",
|
||||
led_state ? "ENCENDIDO" : "DESENCENDIDO",
|
||||
(unsigned long)esp_get_free_heap_size());
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Informações do chip SoC
|
||||
esp_chip_info_t chip_info;
|
||||
esp_chip_info(&chip_info);
|
||||
|
||||
ESP_LOGI(TAG, "===========================================");
|
||||
ESP_LOGI(TAG, " Iniciando ESP-IDF v5.x Modern Application ");
|
||||
ESP_LOGI(TAG, " Modelo do Chip: %d | Núcleos: %d | Rev: %d",
|
||||
chip_info.model, chip_info.cores, chip_info.revision);
|
||||
ESP_LOGI(TAG, "===========================================");
|
||||
|
||||
// Cria uma tarefa FreeRTOS dedicada
|
||||
xTaskCreate(blink_task, "blink_task", 3072, NULL, 5, NULL);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Exemplo ESP-IoT-Solution para ESP32
|
||||
* Inicialização de Botão Inteligente com Callbacks e Driver de Display/Sensores
|
||||
*
|
||||
* Dependência (idf_component.yml):
|
||||
* espressif/button: "^3.3.0"
|
||||
* espressif/led_indicator: "^1.2.0"
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "iot_button.h"
|
||||
#include "led_indicator.h"
|
||||
|
||||
static const char *TAG = "iot_solution_app";
|
||||
|
||||
#define BUTTON_GPIO_NUM 0 // Botão BOOT nativo
|
||||
#define LED_INDICATOR_GPIO 2 // LED indicador
|
||||
|
||||
static led_indicator_handle_t led_handle = NULL;
|
||||
|
||||
/* Callback para clique único do botão */
|
||||
static void button_single_click_cb(void *arg, void *data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Evento: Clique Único detectado!");
|
||||
led_indicator_start(led_handle, BLINK_DOUBLE_FAST);
|
||||
}
|
||||
|
||||
/* Callback para clique longo (> 3 segundos) */
|
||||
static void button_long_press_cb(void *arg, void *data)
|
||||
{
|
||||
ESP_LOGW(TAG, "Evento: Pressionamento Longo! Acionando modo de reset de fábrica.");
|
||||
led_indicator_start(led_handle, BLINK_BREATHE_FAST);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Iniciando ESP-IoT-Solution Component Suite");
|
||||
|
||||
// 1. Configuração do LED Indicator
|
||||
led_indicator_gpio_config_t led_cfg = {
|
||||
.is_active_level_high = true,
|
||||
.gpio_num = LED_INDICATOR_GPIO,
|
||||
};
|
||||
led_handle = led_indicator_create(&led_cfg);
|
||||
|
||||
// 2. Configuração do Botão com debounce de hardware/software automático
|
||||
button_config_t btn_cfg = {
|
||||
.type = BUTTON_TYPE_GPIO,
|
||||
.long_press_time = 3000,
|
||||
.short_press_time = 180,
|
||||
.gpio_button_config = {
|
||||
.gpio_num = BUTTON_GPIO_NUM,
|
||||
.active_level = 0,
|
||||
},
|
||||
};
|
||||
|
||||
button_handle_t btn_handle = iot_button_create(&btn_cfg);
|
||||
assert(btn_handle != NULL);
|
||||
|
||||
// Registra callbacks para diferentes gestos
|
||||
iot_button_register_cb(btn_handle, BUTTON_SINGLE_CLICK, button_single_click_cb, NULL);
|
||||
iot_button_register_cb(btn_handle, BUTTON_LONG_PRESS_START, button_long_press_cb, NULL);
|
||||
|
||||
ESP_LOGI(TAG, "Drivers inicializados com sucesso! Pressione o botão GPIO 0.");
|
||||
|
||||
while (1) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <stdio.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_matter.h"
|
||||
#include "esp_matter_controller.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
static const char *TAG = "esp-matter-example";
|
||||
|
||||
void app_event_cb(const esp_matter_event_t *event)
|
||||
{
|
||||
switch (event->event_id) {
|
||||
case ESP_MATTER_EVENT_ATTRIBUTE_UPDATE: {
|
||||
const esp_matter_attr_update_t *attr_update = &event->data.attr_update;
|
||||
if (attr_update->endpoint_id == 1 && attr_update->cluster_id == ESP_MATTER_ON_OFF_CLUSTER_ID) {
|
||||
bool on = false;
|
||||
esp_matter_attribute_get(attr_update->endpoint_id, attr_update->cluster_id,
|
||||
attr_update->attribute_id, &on);
|
||||
ESP_LOGI(TAG, "Lâmpada %s", on ? "ligada" : "desligada");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Inicializa NVS
|
||||
esp_err_t err = nvs_flash_init();
|
||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
}
|
||||
|
||||
// Inicializa o Matter node
|
||||
esp_matter::node_t *node = esp_matter::node::create(NULL, app_event_cb);
|
||||
esp_matter::endpoint_t *endpoint = esp_matter::endpoint::create(node, ESP_MATTER_ENDPOINT_TYPE_ON_OFF_LIGHT);
|
||||
|
||||
// Inicia la pila Matter
|
||||
ESP_ERROR_CHECK(esp_matter::start(node));
|
||||
|
||||
ESP_LOGI(TAG, "Dispositivo Matter iniciado. Aguardando comissionamento...");
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <stdio.h>
|
||||
#include "esp_nn.h"
|
||||
#include "esp_nn_defs.h"
|
||||
|
||||
#define INPUT_SIZE 4
|
||||
#define OUTPUT_SIZE 3
|
||||
|
||||
void print_array(const char *label, int16_t *array, int size) {
|
||||
printf("%s: ", label);
|
||||
for (int i = 0; i < size; i++) {
|
||||
printf("%d ", array[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Vetor de entrada (ex: saída de uma camada anterior)
|
||||
int16_t input[INPUT_SIZE] = {1, 2, 3, 4};
|
||||
|
||||
// Pesos da camada densa (3x4)
|
||||
int8_t weights[OUTPUT_SIZE * INPUT_SIZE] = {
|
||||
1, -1, 2, 0,
|
||||
0, 1, -1, 1,
|
||||
2, 0, 1, -2
|
||||
};
|
||||
|
||||
// Bias de cada neurônio
|
||||
int16_t bias[OUTPUT_SIZE] = {10, -5, 0};
|
||||
|
||||
// Saída
|
||||
int16_t output[OUTPUT_SIZE];
|
||||
|
||||
// Multiplicação da matriz: output = weights * input + bias
|
||||
esp_nn_mul_mat_16x8_16(weights, input, bias, output,
|
||||
OUTPUT_SIZE, INPUT_SIZE, /*shift=*/0);
|
||||
|
||||
print_array("Antes da ReLU", output, OUTPUT_SIZE);
|
||||
|
||||
// Aplicar função de ativação ReLU
|
||||
esp_nn_relu_16(output, OUTPUT_SIZE);
|
||||
|
||||
print_array("Depois da ReLU", output, OUTPUT_SIZE);
|
||||
}
|
||||
Loaded 100 of 110 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user