File indexing completed on 2024-04-28 12:21:26

0001 /*
0002  * This file is part of KDevelop project
0003  * Copyright 2016 Patrick José Pereira <patrickelectric@gmail.com>
0004  *
0005  * This program is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU Library General Public License as
0007  * published by the Free Software Foundation; either version 2 of the
0008  * License, or (at your option) any later version.
0009  *
0010  * This program is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU General Public
0016  * License along with this program; if not, write to the
0017  * Free Software Foundation, Inc.,
0018  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0019  */
0020 
0021 #include "board.h"
0022 #include "toolkit.h"
0023 
0024 #include <QFile>
0025 #include <QDir>
0026 #include <QDebug>
0027 
0028 #include <QMap>
0029 
0030 #include <interfaces/isession.h>
0031 #include <interfaces/icore.h>
0032 #include <KConfigGroup>
0033 
0034 Q_LOGGING_CATEGORY(BoMsg, "Kdev.embedded.bo.msg")
0035 
0036 using namespace KDevelop;
0037 
0038 void BoardInfo::printData()
0039 {
0040     // Board
0041 
0042     qCDebug(BoMsg) << "name" << m_name;
0043     qCDebug(BoMsg) << "vid"  << m_vid;
0044     qCDebug(BoMsg) << "pid"  << m_pid;
0045 
0046     // Upload
0047 
0048     qCDebug(BoMsg) << "upTool"              << m_upTool;
0049     qCDebug(BoMsg) << "upProtocol"          << m_upProtocol;
0050     qCDebug(BoMsg) << "upMaxSize"           << m_upMaxSize;
0051     qCDebug(BoMsg) << "upMaxDataSize"       << m_upMaxDataSize;
0052     qCDebug(BoMsg) << "upSpeed"             << m_upSpeed;
0053     qCDebug(BoMsg) << "upDisableFlush"      << m_upDisableFlush;
0054     qCDebug(BoMsg) << "upUse1k2bpsTouch"    << m_upUse1k2bpsTouch;
0055     qCDebug(BoMsg) << "upWaitForUploadPort" << m_upWaitForUploadPort;
0056 
0057     // Boot loader
0058 
0059     qCDebug(BoMsg) << "blTool"          << m_blTool;
0060     qCDebug(BoMsg) << "blLowFuses"      << m_blLowFuses;
0061     qCDebug(BoMsg) << "blHighFuses"     << m_blHighFuses;
0062     qCDebug(BoMsg) << "blExtendedFuses" << m_blExtendedFuses;
0063     qCDebug(BoMsg) << "blFile"          << m_blFile;
0064     qCDebug(BoMsg) << "blNoblink"       << m_blNoblink;
0065     qCDebug(BoMsg) << "blUnlockBits"    << m_blUnlockBits;
0066     qCDebug(BoMsg) << "blLockBits"      << m_blLockBits;
0067 
0068     // Build
0069 
0070     qCDebug(BoMsg) << "bMcu"        << m_bMcu;
0071     qCDebug(BoMsg) << "bFcpu"       << m_bFcpu;
0072     qCDebug(BoMsg) << "bVid"        << m_bVid;
0073     qCDebug(BoMsg) << "bPid"        << m_bPid;
0074     qCDebug(BoMsg) << "bUsbProduct" << m_bUsbProduct;
0075     qCDebug(BoMsg) << "bBoard"      << m_bBoard;
0076     qCDebug(BoMsg) << "bCore"       << m_bCore;
0077     qCDebug(BoMsg) << "bVariant"    << m_bVariant;
0078     qCDebug(BoMsg) << "bExtraFlags" << m_bExtraFlags;
0079 
0080     // Not an Option
0081     qCDebug(BoMsg) << "NaO" << m_NaO;
0082 }
0083 
0084 Board::Board()
0085 {
0086     m_listed = false;
0087     m_arduinoFolder = new QFile(Toolkit::instance().arduinoPath());
0088     m_arduinoFolderFail = !m_arduinoFolder->exists();
0089     qCDebug(BoMsg) << "m_arduinoFolderFail" << m_arduinoFolderFail << m_arduinoFolder->fileName();
0090 }
0091 
0092 Board::~Board()
0093 {
0094     delete m_arduinoFolder;
0095 }
0096 
0097 QString Board::getIdFromName(QString _name)
0098 {
0099     update();
0100     foreach (const auto& boardId, m_boardList)
0101     {
0102         if (m_boards[boardId].m_name[0] == _name)
0103         {
0104             return boardId;
0105         }
0106     }
0107     return QString();
0108 }
0109 
0110 Board& Board::instance()
0111 {
0112     static Board self;
0113     return self;
0114 }
0115 
0116 void Board::update()
0117 {
0118     if (!m_listed)
0119     {
0120         load();
0121     }
0122     m_listed = true;
0123 }
0124 
0125 QString Board::Freq2FreqHz(QString freq)
0126 {
0127     return QStringLiteral("%0 %1").arg(QString::number(freq.left(freq.lastIndexOf(QChar::fromLatin1('L'))).toInt() /  1e6)).arg(QStringLiteral("MHz"));
0128 }
0129 
0130 void Board::load()
0131 {
0132     if (m_arduinoFolderFail)
0133     {
0134         qCDebug(BoMsg) << "Board::load" << "error in arduino folder";
0135         return;
0136     }
0137 
0138     qCDebug(BoMsg) << "Board::load m_boardsFile m_arduinoFolder->fileName()" << m_arduinoFolder->fileName();
0139     QFile m_boardsFile(Toolkit::instance().boardFile());
0140     qCDebug(BoMsg) << "Board::load m_boardsFile local" << m_boardsFile.fileName();
0141     bool fileOpened = m_boardsFile.open(QFile::ReadOnly);
0142     qCDebug(BoMsg) << "Board::load fileOpened" << fileOpened;
0143 
0144     // if no boards.txt, nothing to do
0145     if (!fileOpened)
0146     {
0147         return;
0148     }
0149 
0150     QTextStream boardsFileUTF8(&m_boardsFile);
0151     boardsFileUTF8.setCodec("UTF-8");
0152 
0153     while (!boardsFileUTF8.atEnd())
0154     {
0155         const QString line = boardsFileUTF8.readLine().trimmed();
0156 
0157         if (line.isEmpty() || line[0] == QChar::fromLatin1('#'))
0158         {
0159             continue;
0160         }
0161 
0162         QString attrName = line.section(QChar::fromLatin1('='), 0, 0);
0163         const QString attrValue = line.section(QChar::fromLatin1('='), 1);
0164 
0165         // attrName = <product>.<attrName>
0166         const QString productId = attrName.section(QChar::fromLatin1('.'), 0, 0);
0167         attrName = attrName.section(QChar::fromLatin1('.'), 1);
0168 
0169         if (productId.contains(QStringLiteral("menu")))
0170         {
0171             continue;
0172         }
0173 
0174         int lineType = attrName.split(QStringLiteral(".")).size();
0175 
0176         // Normal type
0177         if (lineType != 0)
0178         {
0179             // Board
0180             if (attrName.contains(QStringLiteral("name")))
0181             {
0182                 m_boardList << productId;
0183                 m_boardNameList << attrValue;
0184                 m_boards[productId].m_name << attrValue;
0185             }
0186 
0187             else if (attrName.contains(QStringLiteral("vid")))
0188             {
0189                 m_boards[productId].m_vid << attrValue;
0190             }
0191 
0192             else if (attrName.contains(QStringLiteral("pid")))
0193             {
0194                 m_boards[productId].m_pid << attrValue;
0195             }
0196 
0197             // Upload type
0198             else if (attrName.contains(QStringLiteral("upload.tool")))
0199             {
0200                 m_boards[productId].m_upTool << attrValue;
0201             }
0202 
0203             else if (attrName.contains(QStringLiteral("upload.protocol")))
0204             {
0205                 m_boards[productId].m_upProtocol << attrValue;
0206             }
0207 
0208             else if (attrName.contains(QStringLiteral("upload.maximum_size")))
0209             {
0210                 m_boards[productId].m_upMaxSize << attrValue;
0211                 m_boards[productId].m_upMaxSizeKb << QString::number(attrValue.toInt() / 1024);
0212             }
0213 
0214             else if (attrName.contains(QStringLiteral("upload.maximum_data_size")))
0215             {
0216                 m_boards[productId].m_upMaxDataSize << attrValue;
0217                 m_boards[productId].m_upMaxDataSizeKb << QString::number(attrValue.toInt() / 1024);
0218             }
0219 
0220             else if (attrName.contains(QStringLiteral("upload.speed")))
0221             {
0222                 m_boards[productId].m_upSpeed << attrValue;
0223             }
0224 
0225             else if (attrName.contains(QStringLiteral("upload.disable_flushing")))
0226             {
0227                 m_boards[productId].m_upDisableFlush << attrValue;
0228             }
0229 
0230             else if (attrName.contains(QStringLiteral("upload.use_1200bps_touch")))
0231             {
0232                 m_boards[productId].m_upUse1k2bpsTouch << attrValue;
0233             }
0234 
0235             else if (attrName.contains(QStringLiteral("upload.wait_for_upload_port")))
0236             {
0237                 m_boards[productId].m_upWaitForUploadPort << attrValue;
0238             }
0239 
0240             // Boodloader
0241             else if (attrName.contains(QStringLiteral("bootloader.tool")))
0242             {
0243                 m_boards[productId].m_blTool << attrValue;
0244             }
0245 
0246             else if (attrName.contains(QStringLiteral("bootloader.low_fuses")))
0247             {
0248                 m_boards[productId].m_blLowFuses << attrValue;
0249             }
0250 
0251             else if (attrName.contains(QStringLiteral("bootloader.high_fuses")))
0252             {
0253                 m_boards[productId].m_blHighFuses << attrValue;
0254             }
0255 
0256             else if (attrName.contains(QStringLiteral("bootloader.extended_fuses")))
0257             {
0258                 m_boards[productId].m_blExtendedFuses << attrValue;
0259             }
0260 
0261             else if (attrName.contains(QStringLiteral("bootloader.file")))
0262             {
0263                 m_boards[productId].m_blFile << attrValue;
0264             }
0265 
0266             else if (attrName.contains(QStringLiteral("bootloader.noblink")))
0267             {
0268                 m_boards[productId].m_blNoblink << attrValue;
0269             }
0270 
0271             else if (attrName.contains(QStringLiteral("bootloader.unlock_bits")))
0272             {
0273                 m_boards[productId].m_blUnlockBits << attrValue;
0274             }
0275 
0276             else if (attrName.contains(QStringLiteral("bootloader.lock_bits")))
0277             {
0278                 m_boards[productId].m_blLockBits << attrValue;
0279             }
0280 
0281             // Build
0282             else if (attrName.contains(QStringLiteral("build.mcu")) && !attrValue.contains(QStringLiteral("atmegang")))
0283             {
0284                 m_boards[productId].m_bMcu << attrValue;
0285             }
0286 
0287             else if (attrName.contains(QStringLiteral("build.f_cpu")))
0288             {
0289                 m_boards[productId].m_bFcpu << attrValue;
0290                 m_boards[productId].m_freqHz << Freq2FreqHz(attrValue);
0291             }
0292 
0293             else if (attrName.contains(QStringLiteral("build.vid")))
0294             {
0295                 m_boards[productId].m_bVid << attrValue;
0296             }
0297 
0298             else if (attrName.contains(QStringLiteral("build.pid")))
0299             {
0300                 m_boards[productId].m_bPid << attrValue;
0301             }
0302 
0303             else if (attrName.contains(QStringLiteral("build.usb_product")))
0304             {
0305                 m_boards[productId].m_bUsbProduct << attrValue;
0306             }
0307 
0308             else if (attrName.contains(QStringLiteral("build.board")))
0309             {
0310                 m_boards[productId].m_bUsbProduct << attrValue;
0311             }
0312 
0313             else if (attrName.contains(QStringLiteral("build.core")))
0314             {
0315                 m_boards[productId].m_bCore << attrValue;
0316             }
0317 
0318             else if (attrName.contains(QStringLiteral("build.variant")))
0319             {
0320                 m_boards[productId].m_bVariant << attrValue;
0321             }
0322 
0323             else if (attrName.contains(QStringLiteral("build.extra_flags")))
0324             {
0325                 m_boards[productId].m_bExtraFlags << attrValue;
0326             }
0327 
0328             else
0329             {
0330                 m_boards[productId].m_NaO << QStringLiteral("(%1,%2,%3)").arg(productId).arg(attrName).arg(attrValue);
0331             }
0332         }
0333     }
0334     m_boardsFile.close();
0335 }