diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml
index 4605601e..4422c4f6 100644
--- a/.github/workflows/static-analysis.yml
+++ b/.github/workflows/static-analysis.yml
@@ -81,7 +81,9 @@ jobs:
run: cppcheck --std=c99 --error-exitcode=-1 --inline-suppr --addon=misra.py firmware/system/ --suppress=misra-c2012-19.2
- name: Execute CppCheck on libraries files
- run: cppcheck --std=c99 --error-exitcode=-1 --inline-suppr --addon=misra.py firmware/libs/
+ run: |
+ cppcheck --std=c99 --error-exitcode=-1 --addon=misra.py -I$PWD/firmware/app/libs/ngham-1.0/rsclib/include/ $PWD/firmware/app/libs/ngham-1.0/rsclib/src/*
+ cppcheck --std=c99 --error-exitcode=-1 --addon=misra.py --inline-suppr -I$PWD/firmware/app/libs/ngham-1.0/include/ngham/ -I$PWD/firmware/app/libs/ngham-1.0/include/ $PWD/firmware/app/libs/ngham-1.0/src/* --suppress=misra-c2012-8.4
- name: Execute CppCheck on main files
run: cppcheck --std=c99 --error-exitcode=-1 --addon=misra.py firmware/main.c firmware/version.h
diff --git a/.github/workflows/unit-test-ngham.yml b/.github/workflows/unit-test-ngham.yml
index 5d54b390..fc4e77f8 100755
--- a/.github/workflows/unit-test-ngham.yml
+++ b/.github/workflows/unit-test-ngham.yml
@@ -1,32 +1,33 @@
#
-# unit-test-ngham.yml
+# test.yml
#
-# Copyright The TTC 2.0 Contributors.
+# Copyright The RSCLib Contributors.
#
-# This file is part of TTC 2.0.
+# This file is part of RSCLib.
#
-# TTC 2.0 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# RSCLib is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# TTC 2.0 is distributed in the hope that it will be useful,
+# RSCLib is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with TTC 2.0. If not, see .
+# You should have received a copy of the GNU Lesser General Public License
+# along with RSCLib. If not, see .
#
#
-name: NGHam unit tests
+name: NGHam Unit test
on:
push:
- branches: [dev_firmware]
+ branches: [ dev_firmware ]
pull_request:
- branches: [master, dev, dev_firmware]
+ branches: [ master, dev, dev_firmware]
+
# 'workflow_dispatch' allows manual execution of this workflow under the repository's 'Actions' tab
workflow_dispatch:
@@ -34,7 +35,7 @@ on:
jobs:
unit-tests:
- name: NGHam unit tests
+ name: Unit tests
runs-on: ubuntu-latest
strategy:
@@ -42,22 +43,21 @@ jobs:
steps:
- uses: actions/checkout@v3
+ with:
+ submodules: true
+
- name: Install dependencies
run: |
sudo apt install -y cmake libcmocka0 libcmocka-dev
- git clone https://github.com/mgm8/rsclib.git
- cd rsclib
- mkdir build
- cd build
- cmake ..
- make
- sudo make install
+ mkdir firmware/app/libs/ngham-1.0/tests/build_tests
+ cd firmware/app/libs/ngham-1.0/tests/build_tests
+ cmake ../
- name: Compile the test
run: |
- cd firmware/app/libs/ngham-0.1/tests
- make
+ cd firmware/app/libs/ngham-1.0/tests/build_tests
+ cmake --build .
- name: Execute the test
- run: ./firmware/app/libs/ngham-0.1/tests/ngham_unit_test
+ run: ./firmware/app/libs/ngham-1.0/tests/build_tests/ngham_test
diff --git a/.github/workflows/unit-test-rsclib.yml b/.github/workflows/unit-test-rsclib.yml
index 6d844c2f..934eb624 100644
--- a/.github/workflows/unit-test-rsclib.yml
+++ b/.github/workflows/unit-test-rsclib.yml
@@ -1,32 +1,33 @@
#
-# unit-test-rsclib.yml
+# test.yml
#
-# Copyright The TTC 2.0 Contributors.
+# Copyright The RSCLib Contributors.
#
-# This file is part of TTC 2.0.
+# This file is part of RSCLib.
#
-# TTC 2.0 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# RSCLib is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# TTC 2.0 is distributed in the hope that it will be useful,
+# RSCLib is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with TTC 2.0. If not, see .
+# You should have received a copy of the GNU Lesser General Public License
+# along with RSCLib. If not, see .
#
#
-name: RSCLib unit tests
+name: RSCLib Unit tests
on:
push:
- branches: [dev_firmware]
+ branches: [ dev_firmware ]
pull_request:
- branches: [master, dev, dev_firmware]
+ branches: [ master, dev, dev_firmware]
+
# 'workflow_dispatch' allows manual execution of this workflow under the repository's 'Actions' tab
workflow_dispatch:
@@ -34,7 +35,7 @@ on:
jobs:
unit-tests:
- name: RSCLib unit tests
+ name: Unit tests
runs-on: ubuntu-latest
strategy:
@@ -48,9 +49,9 @@ jobs:
- name: Compile the test
run: |
- cd firmware/app/libs/rsclib-0.1/tests
+ cd firmware/app/libs/ngham-1.0/rsclib/tests
cmake .
make
- name: Execute the test
- run: ./firmware/app/libs/rsclib-0.1/tests/rsc_test
+ run: ./firmware/app/libs/ngham-1.0/rsclib/tests/rsc_test
\ No newline at end of file
diff --git a/doc/user_manual/Makefile b/doc/user_manual/Makefile
index 0060b325..1f7a025e 100644
--- a/doc/user_manual/Makefile
+++ b/doc/user_manual/Makefile
@@ -1,5 +1,5 @@
SRC=main
-VERSION=v0.5
+VERSION=v1.0
TARGET=slb-ttc2-doc-$(VERSION)
ifndef BUILD_DIR
diff --git a/doc/user_manual/chapters/assembly.tex b/doc/user_manual/chapters/assembly.tex
new file mode 100644
index 00000000..f9b927e3
--- /dev/null
+++ b/doc/user_manual/chapters/assembly.tex
@@ -0,0 +1,344 @@
+%
+% assembly.tex
+%
+% Copyright The TTC 2.0 Contributors.
+%
+% TTC 2.0 Documentation
+%
+% This work is licensed under the Creative Commons Attribution-ShareAlike 4.0
+% International License. To view a copy of this license,
+% visit http://creativecommons.org/licenses/by-sa/4.0/.
+%
+
+%
+% \brief Assembly instructions chapter.
+%
+% \author Gabriel Mariano Marcelino
+%
+% \version 1.0.0
+%
+% \date 2021/01/16
+%
+
+\chapter{Assembly instructions} \label{ch:assembly}
+
+This chapter will describe how to customize the radio configuration, power-on the board, import and flash the source code and finally alternatives to encode/decode to be transmitted/received packages from the TTC 2.0 module.
+
+\section{Radio configuration} \label{sec:wds}
+
+This section is a tutorial designed to generate a source code file with basic configuration parameters for the radio module. To achieve this, the WDS software from Silicon Labs (version 3.2.11.0), which is only available on Windows, will be used.
+
+\subsection{Steps}
+
+After the installation of the software, the procedures to configure the beacon radio are described bellow.
+
+\subsubsection{Step 1}
+
+\begin{enumerate}
+ \item Open the WDS software.
+ \item The following box will appear in the center of the window.
+ \item Click in "Simulate radio" and go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.5\textwidth]{figures/wds-tutorial/wds-tutorial-1.png}
+ \caption{Step 1 of the radio configuration.}
+ \label{fig:wds-tutorial-step-1}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 2}
+
+\begin{enumerate}
+ \item In the list of radios that appeared on the new window, select the chip type ``Si4463''.
+ \item In the revision column, select ``B1''.
+ \item Click on ``Select Radio" to go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/wds-tutorial/wds-tutorial-2.png}
+ \caption{Step 2 of the radio configuration.}
+ \label{fig:wds-tutorial-step-2}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 3}
+
+\begin{enumerate}
+ \item Select ``Radio Configuration Application''.
+ \item Click on ``Select Application'' to go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/wds-tutorial/wds-tutorial-3.png}
+ \caption{Step 3 of the radio configuration.}
+ \label{fig:wds-tutorial-step-3}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 4}
+
+\begin{enumerate}
+ \item In the ``Frequency and power'' tab, change the base frequency to 145.9 MHz.
+ \item Change the channel spacing to 0 kHz.
+ \item Change the crystal tolerance to 10.0 ppm (Both RX and TX).
+ \item Go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/wds-tutorial/wds-tutorial-4.png}
+ \caption{Step 4 of the radio configuration.}
+ \label{fig:wds-tutorial-step-4}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 5}
+
+\begin{enumerate}
+ \item In the ``RF parameters" tab, change the modulation type to ``2GFSK''.
+ \item Change the the data rate to 1.2 kbps.
+ \item Change the deviation to 2.5 kHz.
+ \item Go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/wds-tutorial/wds-tutorial-5.png}
+ \caption{Step 5 of the radio configuration.}
+ \label{fig:wds-tutorial-step-5}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 6}
+
+\begin{enumerate}
+ \item In the ``Packet'' tab, many subtabs will appear. In ``Preamble" change the ``Preamble TX length'' to 4 bytes.
+ \item Again, in ``Preamble'', change the ``Preamble pattern'' to ``Std. 1010 pattern (>= 32 and < 40 bits)''.
+ \item Go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/wds-tutorial/wds-tutorial-6.png}
+ \caption{Step 6 of the radio configuration.}
+ \label{fig:wds-tutorial-step-6}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 7}
+
+\begin{enumerate}
+ \item In the ``Sync Word'' tab, change the sync word length field to ``4 bytes''.
+ \item In the ``Sync Word (on air int.)'', enter the following sequence: 5D E6 2A 7E. This sequence is the sync word used by the NGHam protocol.
+ \item Go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/wds-tutorial/wds-tutorial-7.png}
+ \caption{Step 7 of the radio configuration.}
+ \label{fig:wds-tutorial-step-7}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 8}
+
+\begin{enumerate}
+ \item In the ``Field 1'' tab, change the ``Field length'' to 50 bytes.
+ \item Go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/wds-tutorial/wds-tutorial-8.png}
+ \caption{Step 8 of the radio configuration.}
+ \label{fig:wds-tutorial-step-8}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 9}
+
+\begin{enumerate}
+ \item In the ``Variable length config'' tab, there is no values to change.
+ \item Go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/wds-tutorial/wds-tutorial-9.png}
+ \caption{Step 9 of the radio configuration.}
+ \label{fig:wds-tutorial-step-9}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 10}
+
+\begin{enumerate}
+ \item In the ``CRC config'' tab, choose ``No CRC.'' in ``CRC polynomial''.
+ \item Go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/wds-tutorial/wds-tutorial-10.png}
+ \caption{Step 10 of the radio configuration.}
+ \label{fig:wds-tutorial-step-10}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 11}
+
+\begin{enumerate}
+ \item In the ``Whitening config'' tab, there is no values to change.
+ \item Go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/wds-tutorial/wds-tutorial-11.png}
+ \caption{Step 11 of the radio configuration.}
+ \label{fig:wds-tutorial-step-11}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 12}
+
+\begin{enumerate}
+ \item In the ``Field config'' tab, there is no values to change.
+ \item Go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/wds-tutorial/wds-tutorial-12.png}
+ \caption{Step 12 of the radio configuration.}
+ \label{fig:wds-tutorial-step-12}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 13}
+
+\begin{enumerate}
+ \item In the ``Interrupts'' tab, there is no values to change.
+ \item Go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/wds-tutorial/wds-tutorial-13.png}
+ \caption{Step 13 of the radio configuration.}
+ \label{fig:wds-tutorial-step-13}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 14}
+
+\begin{enumerate}
+ \item In the ``GPIO and FRR'' tab, enable pullup in GPIO1 and choose ``TX\_FIFO\_EMPTY - This output is...'' as functionality.
+ \item Enable pullup in GPIO2 and choose ``RX\_STATE - This output is...'' as functionality.
+ \item Enable pullup in GPIO3 and choose ``TX\_STATE - This output is...'' as functionality.
+ \item Enable pullup in NIRQ and choose ``Active low interrupt signal'' as functionality.
+ \item Enable pullup in SDO and choose ``SDO - Output SPI Serial data out.'' as functionality.
+ \item Select ``Global status'' for the ``Fast Response Register A''.
+ \item Select ``Global interrupt pending'' for the ``Fast Response Register B''.
+ \item Select ``Packet Handler status'' for the ``Fast Response Register C''.
+ \item Select ``Chip status'' for the ``Fast Response Register D''.
+ \item Go to the next step.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/wds-tutorial/wds-tutorial-14.png}
+ \caption{Step 14 of the radio configuration.}
+ \label{fig:wds-tutorial-step-14}
+ \end{center}
+\end{figure}
+
+\subsubsection{Step 15}
+
+\begin{enumerate}
+ \item Click in ``Generate Source'' and select the ``.h'' type of source.
+ \item The software will ask where to save the generated file.
+ \item The generated *.h file must be copied to the directory of the rf4463 driver.
+\end{enumerate}
+
+\subsection{Final remarks}
+
+This tutorial has the objective of generate a basic configuration parameters of the radio, some functionalities of the radio are not covered by the WDS software, and so, must be configured/controlled in the device driver.
+
+\section{Powering the module}
+
+The TTC 2.0 has three power supply inputs: one 3V3 supply to power the MCU and all the external components, two 5 V inputs to power the transceivers.
+
+The 3V3 input voltage rail is accessible at the PC-104 H2-27 and H2-28 pins. You can also supply the 3V3 rail with MSP-FET JTAG connector by connecting the jumper CN9. This last option should only be used for debug as it requires the MSP-430 FET to be connected.
+
+The transceiver supply rails are only accessible on the PC-104: H1-49 and H1-50 for radio 0 and H1-51 and H1-52 for radio 1.
+
+The TTC 2.0 module has only one common ground and it can be accessed by multiple pins on the PC-104 (see \autoref {tab:pc104-signals})
+
+It is recommended, for safety reasons, to use different supply channels for each supply rail. Also, for extra safety it is recommended to add current cut-off limits: use 30 mA for the 3V3 and 500 mA for the radio 5 V power rails.
+
+\section{Compiling, building and flashing the source code}
+
+This tutorial is a reference to compile, build and flash the firmware of the TTC 2.0 module using the Texas Instruments IDE: Code Composer Studio (CCS) version 12.
+
+%All the software development was made using the Code Composer Studio (CCS) IDE, version 12. To load the code into the TTC 2.0 MCU, the MSP-FET can be used.
+
+\subsection{Importing the source code in the CCS IDE}
+
+The TTC 2.0 releases are available to download at the TTC 2.0 Github releases page \cite{ttc2-releases}. The CCS IDE is available at the Texas Instruments website \cite{ccs-studio}.
+
+The steps bellow describe how to import the source code in the CCS IDE:
+
+\begin{enumerate}
+ \item Extract the ttc2-x.x.zip file.
+ \item Open the CCS IDE.
+ \item Go to ``Project'' -> ``Import CCS Projects...''.
+ \item The window from the figure \ref{fig:compiling-tutorial} will appear on the screen.
+ \item On ``Select search-directory:'' select ``\textit{project\_path/ttc2-x.x/firmware}''.
+ \item Click on ``Finish''.
+
+ \item After importing the project, select the project on the ``Project Explorer'' and open the ``Properties'' tab (you can use the shortcut \textit{Alt+Enter} or right-click on the project's name).
+ \item The window from the \autoref{fig:project_properties} will appear on the screen.
+ \item On ``Variant'', select the MCU partnumber (MSP430F6659 or MSP430F5659).
+ \item On ``Compiler Version'', select ``TI v21.6.1.LTS'' or higher.
+ \item Click on ``Apply and Close''.
+\end{enumerate}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/ccs_project.png}
+ \caption{New CCS project window.}
+ \label{fig:compiling-tutorial}
+ \end{center}
+\end{figure}
+
+\begin{figure}[!h]
+ \begin{center}
+ \includegraphics[width=0.75\textwidth]{figures/ccs_properties.png}
+ \caption{CCS project's properties window.}
+ \label{fig:project_properties}
+ \end{center}
+\end{figure}
+
+\subsection{Customize the project}
+
+Since the TTC 2.0 has two MCU modules it is needed to specific which one you want to target. Access the configuration header file on the ``Project Explorer" at ``\textit{config/config.h}'', change the ``RADIO\_MODULE'' macro between '0' or '1' (The module '1' is the one closest to the PC-104).
+
+Each MCU module controls a corresponding transceiver, to customize the transceiver configuration (as shown on \autoref{sec:wds}) copy all the code on the header file generated by the WDS software and paste it at the ``config/radio\_x\_config.h''.
+
+\subsection{Compiling and building}
+
+To compile and build the firmware, click on ``Project'' -> ``Build Project''.
+
+\subsection{Flashing}
+
+With the board turned on and the MSP-FET connected, click on ``Run'' -> ``Load''. If no errors occur, the firmware was loaded successfully to the board.
+
+\section{Receiving and sending telecommands}
+
+The structure of the telecommands are described at \autoref{ch:operation}. The standard solution to implement a ground-station is using the SpaceLab transmitter and decoder solutions \cite{sl-transmitter} \cite{sl-decoder} combined with and RTL-SDR.
diff --git a/doc/user_manual/chapters/firmware.tex b/doc/user_manual/chapters/firmware.tex
index f8b47646..3e966bd1 100644
--- a/doc/user_manual/chapters/firmware.tex
+++ b/doc/user_manual/chapters/firmware.tex
@@ -15,7 +15,7 @@
%
% \author Gabriel Mariano Marcelino
%
-% \version 0.3.0
+% \version 1.0.0
%
% \date 2021/05/12
%
@@ -39,54 +39,53 @@ \section{Product tree}
\section{Commands} \label{sec:commands}
-To externally control and access the TTC module, some commands are available through the serial interfaces of the board. The commands are almost identical for both microcontrollers (except the command answering behavior) and are available on all interfaces. A list with the commands is available in \autoref{tab:commands}. The format of the commands' answers can be seen in \autoref{tab:commands-ans}.
+To externally control and access the TTC module, some commands are available through the serial interfaces of the board. The commands are almost identical for both microcontrollers (except the command answering behavior) and are available on all interfaces. A list with the commands is available in \autoref{tab:commands}. The format of the commands answers can be seen in \autoref{tab:commands-ans}.
\begin{table}[!ht]
\centering
+ \scriptsize
\begin{tabular}{clll}
\toprule[1.5pt]
\textbf{ID} & \textbf{Name} & \textbf{Content} & \textbf{Interface}\\
\midrule
0 & NOP & None & SPI \\
- 1 & Read parameter & Parameter ID (1B) + Value (4B) + Checksum (2B) & SPI \\
- 2 & Write parameter & Parameter ID (1B) + Value (4B) + Checksum (2B) & SPI \\
- 3 & Transmit packet & Packet data (1-220B) + Checksum (2B) & SPI/UART \\
- 4 & Receive packet & Packet data (1-220B) + Checksum (2B) & SPI \\
+ 1 & Read parameter & Command ID (1B) + Parameter ID (1B) & SPI \\
+ 2 & Write parameter & Command ID (1B) + Parameter ID (1B) + Value (4B) & SPI \\
+ 3 & Transmit packet & Command ID (1B) + Packet length (1B) + Packet (1-220B) & SPI/UART \\
+ 4 & Receive packet & Command ID (1B) & SPI \\
\bottomrule[1.5pt]
\end{tabular}
- \caption{List of commands.}
+ \caption{List of command's requests.}
\label{tab:commands}
\end{table}
\begin{table}[!ht]
\centering
+ \scriptsize
\begin{tabular}{cll}
\toprule[1.5pt]
\textbf{ID} & \textbf{Name} & \textbf{Content}\\
\midrule
- 1 & Read parameter & Parameter ID (1B) + Value (4B) + Checksum (2B) \\
+ 1 & Read parameter & Command ID (1B) + Parameter ID (1B) + Value (4B) \\
2 & Write parameter & None \\
3 & Transmit packet & None \\
- 4 & Receive packet & Packet data (1-220B) + Checksum (2B) \\
+ 4 & Receive packet & Command ID (1B) + Packet(1-220B) \\
\bottomrule[1.5pt]
\end{tabular}
\caption{Format of the command's answers.}
\label{tab:commands-ans}
\end{table}
-All commands are composed of an ID field (1 byte), the content of the command, and a checksum at the end of the command (2 bytes). The used checksum algorithm is the CRC16-CCITT\nomenclature{\textbf{CRC}}{\textit{Cyclic Redundancy Check.}} \nomenclature{\textbf{CCITT}}{\textit{Comité Consultatif International Téléphonique et Télégraphique.}} (initial value = 0x0000, polynomial = 0x1021). The CRC value is calculated with the entire packet (ID field + command content).
-
-A description of each command is available below:
+A description of each command is available below and the details about the protocol communication are available at \autoref{sec:server_param}.
\begin{itemize}
- \item NOP (No Operation, ID = 1): This command does nothing on the TTC; it is used for reading operations on the SPI interface when an answer to a telecommand is required.
- \item Read parameter/variable (ID = 1): This command is used to read a parameter or variable of the TTC module. It is composed of the command ID (1 byte), the parameter ID (1 byte), and the checksum value (2 bytes). After receiving the command, the answer with the parameter's value can be read with the NOP command (using the SPI interface, with the UART interface, the answer is immediately transmitted). The answer is composed of the command ID (1 byte), the parameter ID (1 byte), the parameter or variable value (4 bytes), and the checksum value (2 bytes).
- \item Write parameter/variable (ID = 2): This command is used to write a value to a given parameter or variable when allowed. It is composed of the command ID (1 byte), the parameter ID (1 byte), the new value of the parameter (4 bytes), and the checksum value (2 bytes). This command has no answer.
- \item Transmit packet (ID = 3): This command is used to transmit a packet through the radio link of each microcontroller. It is composed of the command ID (1 byte), the payload of the packet (1 to 220 bytes), and the checksum value (2 bytes). After receiving it, the TTC immediately transmits a new NGHam packet if the transmissions are enabled. This command has no answer.
- \item Receive packet (ID = 4): This command is used to read a received packet through the radio link (stored in the internal FIFO of the microcontrollers of the TTC). It comprises just the command ID (1 byte) and the checksum value (2 bytes). After receiving it, the TTC immediately allows access to the first available packet. The answer to this command, composed of the command ID (1 byte), the packet content (1 to 220 bytes), and the checksum value (2 bytes) can be read using the NOP command.
+ \item Read parameter/variable (ID = 1): This command is used to read a parameter or variable of the TTC module (see \autoref{tab:ttc2-variables}).
+ \item Write parameter/variable (ID = 2): This command is used to write a value to a given parameter or variable when allowed (see \autoref{tab:ttc2-variables}).
+ \item Transmit packet (ID = 3): This command is used to transmit a packet through the radio link of each microcontroller.
+ \item Receive packet (ID = 4): This command is used to read a received packet through the radio link (stored in the internal FIFO of the microcontrollers of the TTC).
\end{itemize}
-\section{Variables and Parameters} \label{sec:variables}
+\section{Variables and Parameters}\label{sec:variables}
A list of all the variables of TTC with their identification number (ID) and variable type that can be read from the sensors and peripherals can be seen in \autoref{tab:ttc2-variables}.
@@ -96,7 +95,7 @@ \section{Variables and Parameters} \label{sec:variables}
\midrule
0 & Device ID (0xCC2A or 0xCC2B) & uint16 & R \\
1 & Hardware version & uint8 & R \\
- 2 & Firmware version (ex.: ``v1.2.3''' = 0x00010203) & uint32 & R \\
+ 2 & Firmware version (ex.: ``v1.2.3'' = 0x00010203) & uint32 & R \\
3 & Time counter in milliseconds & uint32 & R \\
4 & Reset counter & uint16 & R \\
\multirow{18}{*}{5} & Last reset cause: & \multirow{18}{*}{uint8} & \multirow{18}{*}{R} \\
@@ -151,6 +150,7 @@ \section{Variables and Parameters} \label{sec:variables}
21 & TX packets available in the FIFO buffer & uint8 & R \\
22 & RX packets available in the FIFO buffer & uint8 & R \\
23 & Number of bytes of the first available packet in the RX buffer & uint16 & R \\
+ 24 & Reset TTC 2.0 Module (1=starts reset sequence) & uint8 & W \\
\bottomrule[1.5pt]
\caption{Variables and parameters of the TTC 2.0.}
\label{tab:ttc2-variables}
@@ -160,9 +160,9 @@ \section{Variables and Parameters} \label{sec:variables}
\section{Layers}
-The firmware flow of development goes from the low-level implementation (far right), with HA layer being register-level operation, to Tasks Layer with very abstract and high-level code.
+The firmware flow of development goes from the low-level implementation (far right), with HAL being register-level operation, to Tasks Layer with very abstract and high-level code.
-\subsection{Hardware Abstraction Layer (HAL)}
+\subsection{Hardware Abstraction Layer}
The HAL layer is the API DriverLib developed by Texas Instruments; it includes register manipulating functions to accelerate development. The TTC 2.0 uses HAL to handle GPIO operations and serial communications such as SPI, UART, and I$^2$C.
@@ -185,7 +185,7 @@ \subsection{System}
\begin{figure}[!ht]
\begin{center}
\includegraphics[width=0.65\textwidth]{figures/ttc2-terminal-log.png}
- \caption{Example of log feedback received from TTC 2.0 during debug.}
+ \caption{Example of log feedback received from TTC 2.0}
\label{fig:log_info}
\end{center}
\end{figure}
@@ -199,39 +199,42 @@ \subsection{Tasks}
\begin{tabular}{lccccc}
\toprule[1.5pt]
- \textbf{Name} & \textbf{Priority} & \textbf{Initial delay [ms]} & \textbf{Period [ms]} & \textbf{Stack [bytes]} \\
+ \textbf{Name} & \textbf{Priority\footnote{The priority follows a quantitative pattern, the higher the most important}} & \textbf{Initial delay [ms]} & \textbf{Period [ms]} & \textbf{Stack [bytes]} \\
\midrule
- Automatic Beacon & High & 60000 & 60000 & 300 \\
- Command Processing & Highest & 0 & 100 & 500 \\
- Heartbeat & Lowest & 0 & 500 & 160 \\
- Housekeeping & Medium & 2000 & 10000 & 160 \\
- Radio Reset & High & 60000 & 60000 & 128 \\
- Startup & Medium & 0 & Aperiodic & 128 \\
- System Reset & Medium & 0 & 36000000 & 128 \\
- Time Control & Medium & 1000 & 1000 & 128 \\
- Uplink & Highest & 2000 & 500 & 500 \\
- Watchdog Reset & Lowest & 0 & 100 & 150 \\
+ Antenna Deployment & 6 & 3600000 & 100 & 150 \\
+ Downlink Manager & 3 & 550 & 150 & 2000 \\
+ EPS Server & 3 & 10000 & 750 & 1000 \\
+ Heartbeat & 1 & 2000 & 500 & 160 \\
+ OBDH Server & 5 & 200 & 100 & 2000 \\
+ Radio Reset & 5 & 60000 & 60000 & 128 \\
+ Read Antenna & 2 & 2000 & 60000 & 150 \\
+ Read Sensors & 3 & 2000 & 60000 & 128 \\
+ Startup & 6 & 0 & Aperiodic & 500 \\
+ System Reset & 2 & 0 & 36000000 & 128 \\
+ Time Control & 3 & 1000 & 1000 & 128 \\
+ Uplink Manager & 3 & 500 & 300 & 2000 \\
+ Watchdog Reset & 1 & 0 & 100 & 150 \\
\bottomrule[1.5pt]
\end{tabular}
- \caption{List of TTC 2.0 Tasks with configuration parameters.}
+ \caption{List of TTC 2.0 tasks with configuration parameters.}
\label{tab:firmware-tasks}
\end{table}
Each of the tasks presented in \autoref{tab:firmware-tasks} is described below:
\begin{itemize}
- \item \textbf{Automatic Beacon}: Automatically transmits a beacon packet if no transmission command is received within 60 seconds.
- \item \textbf{Command Processing}: Process incoming commands (physical interfaces).
+ \item \textbf{Antenna Deployment}: Initialize the antenna sequence of deploy after
+ \item \textbf{Downlink Manager}: Monitors for radio request from other tasks and manages downlink FIFO.
+ \item \textbf{EPS Server}: Read only transmit requests from UART bus.
\item \textbf{Heartbeat}: Blinks a status LED at a rate of 1 Hz. Both microcontrollers have a status LED. This LED indicates that the scheduler is up and running.
- \item \textbf{Housekeeping}: This task manages the general operation of the TTC.
+ \item \textbf{OBDH Server}: Read requests and send response from the SPI bus.
\item \textbf{Radio Reset}: Resets the radio at 600 seconds.
+ \item \textbf{Read Antenna}: Reads antenna current status and temperature.
+ \item \textbf{Read Sensors}: Reads the uC and radio temperature and power consumption.
\item \textbf{Startup}: Initializes all the devices and peripherals, and variables of the TTC 2.0 module (boot sequence).
\item \textbf{System Reset}: Resets the microcontroller by software every 10 hours.
- \item \textbf{Time Control}: Manages the system time by loading the saving the time counter from/to the FRAM memory.
+ \item \textbf{Time Control}: Manages the system time by loading the saving the time counter from/to the internal flash memory.
\item \textbf{Uplink Manager}: Monitors the radio module for upcoming packages and stores it in memory.
- \item \textbf{Downlink Manager}: Monitors for radio request from other tasks and manages downlink FIFO.
- \item \textbf{OBDH Server}: Read requests and send response from the SPI bus.
- \item \textbf{EPS Server}: Read only transmit requests from UART bus.
\item \textbf{Watchdog Reset}: Resets both watchdog timers (internal and external) at every 100 milliseconds.
\end{itemize}
@@ -241,4 +244,4 @@ \subsection{Libraries}
\subsection{Tests}
-Tests are used to verify and validate the Drivers and Devices' developed functionality. There are three types of tests: the static test uses the MISRA C: 2012 \cite{misrac2012} guidelines to check for C safety standards, the unitary tests use the Cmocka\footnote{\href{https://cmocka.org/}{https://cmocka.org/}} library with mockups of the hardware, to validate the module in an algorithmic level, and the last test verifies the integration between hardware and firmware.
+Tests are used to verify and validate the Drivers and Devices' developed functionality. There are three types of tests: the static test uses the MISRA-C: 2012 \cite{misrac2012} guidelines to check for C safety standards, the unitary tests use the Cmocka\footnote{\href{https://cmocka.org/}{https://cmocka.org/}} library with mockups of the hardware, to validate the module in an algorithmic level, and the last test verifies the integration between hardware and firmware.
diff --git a/doc/user_manual/chapters/hardware.tex b/doc/user_manual/chapters/hardware.tex
index abae6a09..41a4839d 100644
--- a/doc/user_manual/chapters/hardware.tex
+++ b/doc/user_manual/chapters/hardware.tex
@@ -15,7 +15,7 @@
%
% \author Gabriel Mariano Marcelino
%
-% \version 0.3.0
+% \version 1.0.0
%
% \date 2021/04/02
%
@@ -35,10 +35,10 @@ \chapter{Hardware} \label{ch:hardware}
\begin{figure}[!ht]
\begin{center}
- \subfigure[Upper surface of the TTC 2.0 PCB.\label{fig:ttc2-pcb-top}]{\includegraphics[width=0.48\textwidth]{figures/ttc2_pcb_top}}
+ \subfigure[Top side.\label{fig:ttc2-pcb-top}]{\includegraphics[width=0.48\textwidth]{figures/ttc2_pcb_top}}
~
- \subfigure[Lower surface of the TTC 2.0 PCB.\label{fig:ttc2-pcb-bottom}]{\includegraphics[width=0.48\textwidth]{figures/ttc2_pcb_bottom}}
- \caption{Surfaces of the 3D model of the TTC 2.0 board.}
+ \subfigure[Bottom side.\label{fig:ttc2-pcb-bottom}]{\includegraphics[width=0.48\textwidth]{figures/ttc2_pcb_bottom}}
+ \caption{Top and bottom sides of the TTC 2.0 board.}
\label{fig:ttc2-3d-surface}
\end{center}
\end{figure}
@@ -60,7 +60,7 @@ \section{Specifications}
\item \textbf{Sensors}: Voltage, current and temperature
\item \textbf{Modulation}: (G)FSK and/or (G)MSK
\item \textbf{Baudrate}: 1200 to 9600 bps
- \item \textbf{Frequency}: 145-146 MHz, 435-438 MHz, and/or 450 MHz bands
+ \item \textbf{Frequency}: 145-146, 400-402, 435-438, or 468-469 MHz bands
\item \textbf{Protocol}: NGHam
\item \textbf{Interfaces}: UART, I$^{2}$C and SPI
\item \textbf{Mass}: 73 g
@@ -73,7 +73,7 @@ \section{Electrical interfaces}
\subsection{PC-104 bus}
-The connector PC-104 is a junction of two double rows 26 pin headers (\textit{SSW-126-04-G-D} by default). These connectors create a solid 104-pin interconnection across the different satellite modules. \autoref{tab:pc104-pinout} provides the connector pinout\footnote{This pinout is simplified since additional interfaces were omitted.} for the pins that are connected to the module. A reference of the pins' position can also be seen in \autoref{fig:pc104-ref-diagram}, and a description of the signal is available in \autoref{tab:pc104-signals}.
+The connector PC-104 is a junction of two double rows 26 pin headers (\textit{SSW-126-04-G-D} by default). These connectors create a solid 104-pin interconnection across the different satellite modules. \autoref{tab:pc104-pinout} provides the connector pinout\footnote{This pinout is simplified since additional interfaces were omitted.} for the pins that are connected to the module. A reference of the pin's position can also be seen in \autoref{fig:pc104-ref-diagram}, and a description of the signal is available in \autoref{tab:pc104-signals}.
\begin{figure}[!ht]
\begin{center}
@@ -190,7 +190,7 @@ \subsection{Dedicated electrical interfaces}
\midrule
\multirow{10}{*}{CN5} & \multirow{10}{*}{\raisebox{-\totalheight}{\includegraphics[width=4cm]{figures/cn5}}} & \multirow{10}{*}{JTAG} & \multirow{10}{*}{PicoBlade} & \\
& & & & \\
- & & & & 3V3 \\
+ & & & & 3V3\_JTAG \\
& & & & TDO\_TDI \\
& & & & TCK \\
& & & & UART\_TX \\
@@ -201,7 +201,7 @@ \subsection{Dedicated electrical interfaces}
\midrule
\multirow{10}{*}{CN6} & \multirow{10}{*}{\raisebox{-\totalheight}{\includegraphics[width=4cm]{figures/cn6}}} & \multirow{10}{*}{JTAG} & \multirow{10}{*}{PicoBlade} & \\
& & & & \\
- & & & & 3V3 \\
+ & & & & 3V3\_JTAG \\
& & & & TDO\_TDI \\
& & & & TCK \\
& & & & UART\_TX \\
@@ -239,15 +239,15 @@ \subsection{Dedicated electrical interfaces}
& & & & \\
& & & & \\
& & & & \\
+ & & & & 3V3\_JTAG \\
& & & & 3V3 \\
- & & & & - \\
& & & & \\
& & & & \\
& & & & \\
& & & & \\
\midrule
\multirow{14}{*}{CN3} & \multirow{14}{*}{\raisebox{-\totalheight}{\includegraphics[width=4cm]{figures/cn3}}} & \multirow{14}{*}{JTAG} & \multirow{14}{*}{Pin Header} & TDO\_TDI \\
- & & & & 3V3 \\
+ & & & & 3V3\_JTAG \\
& & & & None \\
& & & & None \\
& & & & None \\
@@ -265,7 +265,7 @@ \subsection{Dedicated electrical interfaces}
\pagebreak
\midrule
\multirow{14}{*}{CN4} & \multirow{14}{*}{\raisebox{-\totalheight}{\includegraphics[width=4cm]{figures/cn4}}} & \multirow{14}{*}{JTAG} & \multirow{14}{*}{Pin Header} & TDO\_TDI \\
- & & & & 3V3 \\
+ & & & & 3V3\_JTAG \\
& & & & None \\
& & & & None \\
& & & & None \\
@@ -307,15 +307,15 @@ \subsection{Dedicated electrical interfaces}
\section{Mechanical interfaces}
-The TTC 2.0 board has four mounting holes to fix the module into the CubeSat mechanical structure. These mounting holes are 3,2 mm in diameter and positioned on each corner of the PCB. These holes can be seen in Figures \ref{fig:ttc2-pcb-top} and \ref{fig:ttc2-pcb-bottom}.
+The TTC 2.0 board has four mounting holes to fix the module into the CubeSat mechanical structure. These mounting holes are 3.2 mm in diameter and positioned on each corner of the PCB. These holes can be seen in Figures \ref{fig:ttc2-pcb-top} and \ref{fig:ttc2-pcb-bottom}.
-\section{Printed Circuit Board (PCB)}
+\section{Printed Circuit Board}
This section presents some detailed information about the PCB of the TTC 2.0 module.
\subsection{Dimensions}
-The TTC PCB dimensions follow the CubeSats industry standards defined by ISISpace and GomSpace, with a size of $89,15$ mm by $92,13$ mm \cite{nasa-handout}. The outline is specifically defined to improve the physical integration of modules and payloads into the mechanical structure. A drawing with the board dimensions is available in \autoref{fig:board-dimensions}.
+The TTC PCB dimensions follow the CubeSats industry standards, with a size of $89.15$ mm by $92.13$ mm \cite{nasa-handout}. The outline is specifically defined to improve the physical integration of modules and payloads into the mechanical structure. A drawing with the board dimensions is available in \autoref{fig:board-dimensions}.
\begin{figure}[!ht]
\begin{center}
@@ -327,7 +327,7 @@ \subsection{Dimensions}
\subsection{Layout}
-The TTC 2.0 module contains only two layers: top and bottom, as presented in Figures \ref{fig:ttc2-pcb-top} and \ref{fig:ttc2-pcb-bottom}.
+The TTC 2.0 module contains only two layers: top and bottom, as presented in Figures \ref{fig:ttc2-pcb-top} and \ref{fig:ttc2-pcb-bottom}. To design the layout, the Altium Designer\footnote{\href{https://www.altium.com/}{https://www.altium.com/}} software was used.
\begin{figure}[!ht]
\begin{center}
@@ -345,13 +345,11 @@ \subsection{Layout}
\end{center}
\end{figure}
-To design the layout, the Altium Designer\footnote{\href{https://www.altium.com/}{https://www.altium.com/}} software was used.
-
-Simple PCBs with common manufacturing specifications were used to test and develop the module. These PCBs were defined as Engineering Models (EM\nomenclature{\textbf{EM}}{\textit{Engineering Model.}}). The Flight Model (FM\nomenclature{\textbf{FM}}{\textit{Flight Model.}}, or the boards that fly with the satellite) of the boards have the following manufacturing specifications:
+Simple PCBs with common manufacturing specifications were used to test and develop the module. These PCBs were defined as Engineering Models (EM). The Flight Model (FM, or the boards that can fly with the satellite) of the boards have the following manufacturing specifications:
\begin{itemize}
\item \textbf{PCB specs.}: IPC 6012 Class 3
- \item \textbf{PCB thickness}: 1,6 mm
+ \item \textbf{PCB thickness}: 1.6 mm
\item \textbf{Material}: TG170 FR-4
\item \textbf{Surface finish}: ENIG
\item \textbf{Board finish}: Conformal coating application
@@ -363,7 +361,7 @@ \section{Peripherals}
\subsection{Power sensor}
-The board has power sensors (model INA226AQDGSRQ1 from Texas Instruments) that use an I$^{2}$C interface to communicate with the microcontroller. There are four of these sensors in the module, one for each microcontroller and one for each radio module. It monitors voltage and current from a given bus through a shunt resistor (with a resistance of $0,1$ $\Omega$). The final measurement is continuous and made by an average of 128 measurements with an interval of 588 $\mu$s between each other.
+The board has power sensors (model INA226AQDGSRQ1 from Texas Instruments) that use an I$^{2}$C interface to communicate with the microcontroller. There are four of these sensors in the module, one for each microcontroller and one for each radio module. It monitors voltage and current from a given bus through a shunt resistor (with a resistance of $0.1$ $\Omega$). The final measurement is continuous and made by an average of 128 measurements with an interval of 588 $\mu$s between each other.
\subsection{External watchdog timer}
@@ -371,7 +369,7 @@ \subsection{External watchdog timer}
\subsection{Radio module}
-One of the main components of the board is the radio module (NiceRF RF4463F30), which uses an SPI interface to be controlled by the microcontroller. The radio has a dedicated power source of 5V directly from the PC-104 bus. The output power of the RF signal generated by the radio is 30 dBm (1 W). The radio is half-duplex and has an integrated power amplifier and an RF switch, as shown in \autoref{fig:rf4463f30-block-diagram}.
+One of the main components of the board is the radio module (NiceRF RF4463F30), which uses an SPI interface to be controlled by the microcontroller. The radio has a dedicated power source of 5 V directly from the PC-104 bus. The output power of the RF signal generated by the radio is 30 dBm (1 W). The radio is half-duplex and has an integrated power amplifier and an RF switch, as shown in \autoref{fig:rf4463f30-block-diagram}.
\begin{figure}[!ht]
\begin{center}
@@ -379,4 +377,4 @@ \subsection{Radio module}
\caption{Block diagram of the RF4463F30 module.}
\label{fig:rf4463f30-block-diagram}
\end{center}
-\end{figure}
\ No newline at end of file
+\end{figure}
diff --git a/doc/user_manual/chapters/introduction.tex b/doc/user_manual/chapters/introduction.tex
index c9a63d01..d028f1e4 100644
--- a/doc/user_manual/chapters/introduction.tex
+++ b/doc/user_manual/chapters/introduction.tex
@@ -15,7 +15,7 @@
%
% \author Gabriel Mariano Marcelino
%
-% \version 0.3.0
+% \version 1.0.0
%
% \date 2021/04/01
%
@@ -23,14 +23,14 @@
\chapter{Introduction} \label{ch:introduction}
-The TTC 2.0\nomenclature{\textbf{TTC}}{\textit{Telemetry, Tracking and Command.}} is a Telemetry, Tracking and Command module designed for nanosatellites. It is one of the service modules developed for the GOLDS-UFSC CubeSat Mission \cite{floripasat2}.
+The TTC 2.0 is a Telemetry, Tracking and Command module designed for nanosatellites. It is one of the service modules developed for the GOLDS-UFSC CubeSat Mission \cite{floripasat2}, and part of the FloripaSat-2 platform \cite{marcelino2023}.
The module is a direct upgrade from the TTC of FloripaSat-1 \cite{ttc-fsat}, which grants a flight heritage rating. The improvements focus on providing a cleaner and more generic implementation than the previous version, more reliability in software and hardware implementations, and adaptations for the new mission requirements. All the project, source, and documentation files are available freely on a GitHub repository \cite{ttc2-repo} under the GPLv3 (firmware) and CERN OHLv2 (hardware) licenses.
\begin{figure}[!h]
\begin{center}
\includegraphics[width=0.65\textwidth]{figures/ttc2_pcb_3d.png}
- \caption{3D view of the TTC 2.0 PCB\nomenclature{\textbf{PCB}}{\textit{Printed Circuit Board.}}.}
+ \caption{3D view of the TTC 2.0 PCB.}
\label{fig:pcb-3d}
\end{center}
\end{figure}
@@ -45,4 +45,5 @@ \section{Product tree}
\caption{Product tree of the TTC 2.0 module.}
\label{fig:product-tree}
\end{center}
-\end{figure}
\ No newline at end of file
+\end{figure}
+
diff --git a/doc/user_manual/chapters/operation.tex b/doc/user_manual/chapters/operation.tex
index 89ad56f3..2bddf911 100644
--- a/doc/user_manual/chapters/operation.tex
+++ b/doc/user_manual/chapters/operation.tex
@@ -15,7 +15,7 @@
%
% \author Gabriel Mariano Marcelino
%
-% \version 0.3.0
+% \version 1.0.0
%
% \date 2022/10/09
%
@@ -27,7 +27,7 @@ \chapter{Operation} \label{ch:operation}
\section{Packet transmission}
-To transmit a packet, the command ``Transmit Packet'' must be used (\autoref{sec:commands}). When the TTC receives this command through one of its command interfaces, a new NGHam packet is generated with the command content as the packet's payload. After the NGHam packet is generated, it is transmitted immediately through the air using the respective TTC's radio.
+ To transmit a packet, the command ``Transmit Packet'' must be used (\autoref{sec:commands}). When the TTC receives this command through one of its command interfaces, a new NGHam packet is generated with the command content as the packet's payload. After the NGHam packet is generated, it is transmitted immediately through the air using the respective TTC's radio.
\section{Telecommand reception}
@@ -35,7 +35,7 @@ \section{Telecommand reception}
A telecommand is only stored if it is a valid NGHam packet, and only the payload of the NGHam packet is stored. Each telecommand can be up to 220 bytes long, according to the NGHam protocol definitions.
-The received and stored telecommand can be read with the command read packet, as described in \autoref{sec:commands}. After a telecommand is read, it is deleted from the internal queue of the TTC module. The number of available telecommands and the length in bytes of the first queue position can be read using the command ``Read Parameter'', as also described in \autoref{sec:commands} and \ref{sec:variables}.
+The received and stored telecommand can be read with the command read packet, as described in \autoref{sec:commands}. After a telecommand is read, it is deleted from the internal queue of the TTC module. The number of available telecommands and the length in bytes of the first queue position can be read using the command ``Read Parameter'', as also described in Sections \ref{sec:commands} and \ref{sec:variables}.
\section{Communication protocol}
@@ -131,9 +131,7 @@ \subsubsection{Reed-Solomon block}
\item \textbf{Final XOR value}: 0xFFFF
\end{itemize}
-The CRC16 value is computed from the header and the payload fields.
-
-If the CRC16 value is correct, the Reed-Solomon chain is skipped, and the packet is directly considered valid. This way, the checksum field also allows a performance improvement.
+The CRC16 value is computed from the header and the payload fields. If the CRC16 value is correct, the Reed-Solomon chain is skipped, and the packet is directly considered valid. This way, the checksum field also allows a performance improvement.
\paragraph{Padding}
@@ -158,7 +156,7 @@ \subsubsection{Reed-Solomon block}
7 & RS(255, 233) & 32 \\
\bottomrule[1.5pt]
\end{tabular}
- \caption{.}
+ \caption{NGHam parity sizes.}
\label{tab:ngham-parity}
\end{table}
@@ -191,17 +189,18 @@ \section{Flow of execution}
\end{center}
\end{figure}
-\section{Server Paramater}
+\section{Server parameter}\label{sec:server_param}
There are two main serial ports accessible to communicate with the TTC module a UART that is accessible only for the radio 1 and can only transmit packages. The other port is an SPI and is possible to communicate individually with each microcontroller and you can requisite all the commands and parameters (see Tables \ref{tab:commands} and \ref{tab:ttc2-variables}). The protocol communication is described below.
-\subsection{EPS Server}
+\subsection{EPS server}
+
The EPS Server is in RX mode and only the Transmit packet command (ID=3) is available. To transmit a package the first byte shall be the command (0x03) followed by the packet. The UART configuration is resumed on Table \ref{tab:eps_config}. This serial port can be accessed via the pin 5 of the PC104-H2 pin 7 is connected to TX but is not utilized, see Table \ref{tab:pc104-pinout}.
\begin{table}[!ht]
\centering
- \begin{tabular}{clll}
+ \begin{tabular}{lc}
\toprule[1.5pt]
\textbf{Configuration Parameter} & \textbf{Value}\\
\midrule
@@ -224,9 +223,10 @@ \subsection{EPS Server}
\end{center}
\end{figure}
-\subsection{OBDH Server}
-The OBDH Server can be used for full communication and all the commands are implemented for this port. The TTC operates as half-duplex with the commands having a request and a followed by response (except for command Write parameter ID=2 that only uses a request). For commands that need a response it is required to leave a interval of at least 100ms from the request to the response. Each communication part, for both sides, in all commands starts with the preamble byte (0x7E) that can be used to detect and sincronize wrong transactions. When each side is communicating the listening side needs to send 0x00 while the other side transmits.
-All the request have seven bytes length including the preamble, the response for command ID=1 also has 7 bytes as fixed size, the response from commands ID=3 and ID=4 have a variable size accordingly to the request. The communication for each case is described in Figure \ref{fig:obdh-server-communication}. The TTC operates in spi mode 0 and was tested with 1 MHz clock.
+\subsection{OBDH server}
+
+The OBDH Server can be used for full communication and all the commands are implemented for this port. The TTC operates as half-duplex with the commands having a request and a followed by response (except for command Write parameter ID=2 that only uses a request). For commands that need a response it is required to leave a interval of at least 100ms from the request to the response. Each communication part, for both sides, in all commands starts with the preamble byte (0x7E) that can be used to detect and synchronize wrong transactions. When each side is communicating the listening side needs to send 0x00 while the other side transmits.
+All the request have seven bytes length including the preamble, the response for command ID=1 also has 7 bytes as fixed size, the response from commands ID=3 and ID=4 have a variable size accordingly to the request. The communication for each case is described in Figure \ref{fig:obdh-server-communication}. The TTC operates in SPI mode 0 and was tested with 1 MHz clock.
\begin{figure}[!ht]
\begin{center}
@@ -238,14 +238,14 @@ \subsection{OBDH Server}
\begin{table}[!ht]
\centering
- \begin{tabular}{clll}
+ \begin{tabular}{lc}
\toprule[1.5pt]
\textbf{Configuration Parameter} & \textbf{Value}\\
\midrule
- Mode & 0 \\
- Clock & 200 kHz to 1 MHz \\
+ Mode & 0 \\
+ Clock & 200 kHz to 1 MHz \\
\bottomrule[1.5pt]
\end{tabular}
\caption{OBDH Server configuration parameter.}
\label{tab:eps_config}
-\end{table}
\ No newline at end of file
+\end{table}
diff --git a/doc/user_manual/chapters/references.tex b/doc/user_manual/chapters/references.tex
index c7843d46..c6bfb7bc 100644
--- a/doc/user_manual/chapters/references.tex
+++ b/doc/user_manual/chapters/references.tex
@@ -15,7 +15,7 @@
%
% \author Gabriel Mariano Marcelino
%
-% \version 0.3.0
+% \version 1.0.0
%
% \date 2021/04/01
%
@@ -31,6 +31,12 @@
references/ccsds,%
references/pyngham-doc,%
references/misrac2012,%
- references/nasa-handout}
+ references/nasa-handout,%
+ references/marcelino2023,%
+ references/ccs-studio,%
+ references/ttc2-releases,%
+ references/sl-transmitter,%
+ references/sl-decoder,%
+ references/references}
\addcontentsline{toc}{chapter}{References}
diff --git a/doc/user_manual/figures/ccs_project.png b/doc/user_manual/figures/ccs_project.png
new file mode 100644
index 00000000..bb76eab4
Binary files /dev/null and b/doc/user_manual/figures/ccs_project.png differ
diff --git a/doc/user_manual/figures/ccs_properties.png b/doc/user_manual/figures/ccs_properties.png
new file mode 100644
index 00000000..1ab602d4
Binary files /dev/null and b/doc/user_manual/figures/ccs_properties.png differ
diff --git a/doc/user_manual/figures/product-tree-fw.drawio b/doc/user_manual/figures/product-tree-fw.drawio
index 9c5cd2cf..fb3cbe03 100644
--- a/doc/user_manual/figures/product-tree-fw.drawio
+++ b/doc/user_manual/figures/product-tree-fw.drawio
@@ -1 +1,633 @@
-7V1tc+I2EP41zLQfLmP5DftjApdL2qSXBto0H31GBU/ApsYJob++ZrDB7BoCrqVVwLm5GfyCLR49u9pdrVYtozN5/xZ709F9NODjlq4N42DQMrotXWfp//TE1BvyrRPLO3rBv/lJLTv7Ggz4bOvGJIrGSTDdPulHYcj9ZOucF8fRfPu2v6MxbkbP98YcnX0KBsloddYwNG1z4YYHw1H2pvSSu7oy8fK7s1tnI28QzQunjK8toxNHUbL6NHnv8PESmhyY1feud1xdtyzmYXLIF+a/xl+6nUmv/8fzn//evFt//j785Uv2lDdv/Jr94m4cvPF4lrU5WeRIxNFrOODLZ7GWcTUfBQnvTT1/eXWedmx6bpRMxtnl7Kk8Tvj7zuayNQgpN3g04Um8SG/JvmDYGW6L1bFpZsfzTT+wHNtRoQvy73lZTw/Xj96Ak37I8DkCKx1jxd8Cn9NjZemqYWUgrPre7IUeKaZpqkFlIqguux1yoNa4LADFyHCyEE7XY282Ug4pW6NGykZIfXu4/a4eUA41UG0E1K2unui1bWqcHIzTb5e6/q4cVA65NnexNg+TnnJAueTqPDfoC0j1AtO01SPVxmagAwvb6b2H2/TET/feLOHxzwqCRq7dGTbYM9B6Y++NK4gZI9f0rMRwf+gZjoK6nunkyp5h2/2p21cPKZNegWGb9I/LRwWhMugHRmxtIZh4OLhcBrPSIz91gmaBv43MBkYtPUqxiBd/FQ+elwcXVn7YfS9e7C7yo/cg+WtzZ3r0nD1/+XnzpeVB/p1VU/kABPNQj6Q/J3qNfb4PiNV9iRcPebLnPrO8hwsdaJX0X34u5mMvCd62m1vWqdkbHqIg/SGbMJUB/GQH8GL1M7Nv6YXwHHyQAx5kgAetcEAPSnngLQq3TZc3zHY32ASxIsvaChumH1ZP3BB4jen/4DQ2ixtO7+O0RclpHXC6zSpyWgectqHSFMRp25DA6fydDacP5LRNqqd3BVWO1tPuB8IhiNP5e8RyGvuZDaf3cbpNqqfBFJlTVU8b7APhEMVpVwancRig4fQ+TjtKcdqtidPr0LBgTjttGZzGYZqG0/s47arEaabVpahdSYraleEk6jia1pB6H6mZ1iJkNbKo9aqkdqB4WHJYzTQpfiJOXGhovZfWO0K2kmhtlduox9Maso1JiugxJsVVxBH9htZ7aa2T0hrE9JheNVCN6KZrsngtxV3ESUENr/fy2qDkNUOzwu2KvGYufBI0aETxWpfiMjbTikfymjZezaCt6loXzNr80ytaJSD/mRmyrBJDig/ZTDQWWE5GXkAyp7KtgTJZZLHVlOEaGjpi62WY8DD0EGllJ8bYoAvp8/8NHPO854NAPajo89oNHEl7iOY8Tk/1eDiLYuUwo89xN3CY5tEbBJFyUNHnuBvY9e/zyZTHXvIa85Zuj9MWXP1IWWYPl58U5Rx9DryBfc0nL/FHg2ioHFoKZMGbeLi8+9pVDin6BWAmHiqvuOdHITlWm2UBytgVJh4sb7gXJz+4l6iHlwLk2jlQao98xlXEjNwgM/GI+ci9wdoeU2FhtKOaRWbi0bGXunvJ61Q9tOiNMhPH93qLWcIn6solvQFm4nBRP5ikJqzWicIkjsbqgaaAHZZHiYqLeabjIHxJz917oTfk9MZ+CW7ko4BVUm0lmofKI0e/LDGPdp99WDf72R9OXqwii1TxXwvkUNgwanto/BdFIWEguabwrwW9EhlzFVaTxHkcqU1aUoMMChtmqR1Kakg2W1D+BHqPjCkN6yySOMk4CPUUpE5VxSpqFRNssJRVTNZZZFyeHgdhpqUoDspII7POIj2SioNMs2siIQ5IC0o+x02WYmOeRTbjCdIQuUyiaCjHKjyL5MMTpGFqr11ohT/QNlGklGMmnkWu4CmSUpChiGkow1LM39nQUIi30nYv3OJfPZy03H2PdeAaBEGejJS15vZZ1AQ5QTUpioWoyXJoqDc0PDE16QpytaGalFK9wD6L2ZwTVJOiWIiaLIeGTez7M8a+16UoROtCOTUv7Cb6/TmVoTAeojZLImITePykRGSCZqQxEaWUS8l9sYaIn46IsqKNcuqbtEt2eOinj9L0Cw0v3bsO4sk87WXEVdlZqW0AlkGecN/GmU59PksUWMoBK0/R73HXLlkz1P9Ovy2S7SiHFLacr2POlUALyiD92r02Tm+4ubwjB0rXlKMVtoNXG73eBT/o4VJuTWj7LKaGD0jNzgXs40LopFWjGVxwUDU3G0quqNxsWBJYSjJYLmYlSwSJNYBjqqYwnfpnPStI8kZrbBTF85aeKNcadWoA41ANQLoXAqwUZVQtA2iCMoBrY7pmDeBAI13X9rYLagxwvyCNoTdScJwU0E5PgCVKRtVNbuCsgSEoGHesEMAybXKEQOCSpuMITW0MHioEOqUQtKEtUT15YftBqLIskRBA4ZQjBPXPK5/4SNAm3cPPBfVjDbj9zaFS4AK7QxcUDj9WCpCYS5GC+ue1T1wKVrqKSgocq6axwAVxAUNQ0tCxUgDbJUcKBC4qO02DiLREfm0G0WbfqlwKBCWLHCsFaCpVjhgIzC05TTFYTZmSBYkhS4yqW/tsklN2WVdUggD30pIjCGcxW6KK+q6c2oKmbwXZMKjBMuY2clEucLAzjvwX+nQMF8gw/eymi+c2bqJIQajoi926OoKqx1WoQIqgIq9u6OLEsjsF6phDoOjr2rpnUSLrALsxp+zHu/eSBhHguGnDIoSHDsAOsBpF1fiAQQE5A3Cz5ENkOBd2aeVAFhw3JHFQSpkZt1nt8Rk5KKr4IGywlKoybuMMf0oOCprWQhyUscaD5S9F6b70Ph4zYReS+8NMww5xl78FPlcQLnqfmGnYKb6P/JfXqYpwkfvFTGuW5IuM6sOQd/Wlf0gziaoMgZosw0FjWmMdf04eCqsFCpssxUljWmMhf04eivLTUJPrdtTMWdI3rEf76vd4vAin4XzkX3/BNt9d8CP24kAFq4/BhAaZC2JK4cI233KLLC8IlXAqdDjnKNOpKMULz4b89u3Go19qhaCS6lCUQqVYavFxY8ih48H2fMg+jVScDtktimTjyzoNHk6oHT2+wDoFwsYXHU7B12xvl/aSYqnCyrOaNEcSacV21Xx5poNlI7ao+jGQ1XVb76W9VH/q7+kkwO+mP1m4HC5mrboqlmlwfa0iy2KRFNSd8die/3Lr377+03kJ+7Pnp64/6wQlvkNeOmkQvOW1k75fdW9ayx2e47fltp6r6+nrCrcg2aHf7FOX6WmUgos9ja8PvQKQykFmyHQ2SiHDzsaTl/ijwTL/Cpb0UnQz6E20gQzFsrysXVKtqDzjurIy5z9KUcXe3Uqc1cNK6j7HpVg1u3XJLN5cNY8PE0fS7pm1lyotJWEzTSSRhHbV6AkmoaTtM2svU1pKwmaOSGq53KqqsMR/kLXrzPpNYj09nEnVEFEcESurwxKvTNa+Hus3iSVi/QXpGiLu7tTq8V/s2ErbUsH8fxHg9DCOoqR4e+p3je6jAV/e8R8=
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/user_manual/figures/product-tree-fw.pdf b/doc/user_manual/figures/product-tree-fw.pdf
index 844c3b6c..c07a2d00 100644
Binary files a/doc/user_manual/figures/product-tree-fw.pdf and b/doc/user_manual/figures/product-tree-fw.pdf differ
diff --git a/doc/user_manual/figures/ttc2-terminal-log.png b/doc/user_manual/figures/ttc2-terminal-log.png
index 7f7aedb8..94aea591 100644
Binary files a/doc/user_manual/figures/ttc2-terminal-log.png and b/doc/user_manual/figures/ttc2-terminal-log.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-1.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-1.png
new file mode 100644
index 00000000..5b648d60
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-1.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-10.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-10.png
new file mode 100644
index 00000000..d10130f9
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-10.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-11.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-11.png
new file mode 100644
index 00000000..80fef401
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-11.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-12.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-12.png
new file mode 100644
index 00000000..44655ff8
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-12.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-13.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-13.png
new file mode 100644
index 00000000..7f500b87
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-13.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-14.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-14.png
new file mode 100644
index 00000000..38ded717
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-14.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-2.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-2.png
new file mode 100644
index 00000000..136aad8d
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-2.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-3.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-3.png
new file mode 100644
index 00000000..5c5ee47a
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-3.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-4.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-4.png
new file mode 100644
index 00000000..b1ac04ad
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-4.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-5.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-5.png
new file mode 100644
index 00000000..ed418183
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-5.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-6.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-6.png
new file mode 100644
index 00000000..9ad52a8d
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-6.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-7.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-7.png
new file mode 100644
index 00000000..385eae55
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-7.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-8.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-8.png
new file mode 100644
index 00000000..863e32ff
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-8.png differ
diff --git a/doc/user_manual/figures/wds-tutorial/wds-tutorial-9.png b/doc/user_manual/figures/wds-tutorial/wds-tutorial-9.png
new file mode 100644
index 00000000..5704870c
Binary files /dev/null and b/doc/user_manual/figures/wds-tutorial/wds-tutorial-9.png differ
diff --git a/doc/user_manual/header/authorpage.tex b/doc/user_manual/header/authorpage.tex
index 7c862f57..c5c58dd5 100644
--- a/doc/user_manual/header/authorpage.tex
+++ b/doc/user_manual/header/authorpage.tex
@@ -15,7 +15,7 @@
%
% \author Gabriel Mariano Marcelino
%
-% \version 0.5.0
+% \version 1.0.0
%
% \date 2021/04/01
%
@@ -26,7 +26,7 @@
\textbf{\thetitle}
-\textit{November, 2023}
+\textit{September, 2024}
\vspace{1cm}
@@ -46,6 +46,7 @@
\textbf{Contributing Authors:}
+Carlos Augusto Porto Freitas \\
Sara Vega Martinez \\
Vitória Beatriz Bianchin \\
Yan Castro de Azeredo \\
@@ -62,12 +63,14 @@
\toprule[1.5pt]
\textbf{Version} & \textbf{Author} & \textbf{Changes} & \textbf{Date} \\
\midrule
- 0.0 & G. M. Marcelino & Document creation & 2021/04/01 \\
- 0.1 & G. M. Marcelino & First release & 2021/06/16 \\
- 0.2 & G. M. Marcelino & General improvements and updates & 2022/05/17 \\
- 0.3 & G. M. Marcelino, M. Boing & General improvements and updates & 2022/11/04 \\
- 0.4 & M. Boing & Firmware updates & 2023/03/19 \\
- 0.5 & M. Boing & Serial interfaces & 2023/11/01\\
+ v0.0 & G. M. Marcelino & Document creation & 2021/04/01 \\
+ v0.1 & G. M. Marcelino & First release & 2021/06/16 \\
+ v0.2 & G. M. Marcelino & General improvements and updates & 2022/05/17 \\
+ v0.3 & G. M. Marcelino, M. Boing & General improvements and updates & 2022/11/04 \\
+ v0.4 & M. Boing & Firmware updates & 2023/03/19 \\
+ v0.5 & M. Boing & Firmware updates & 2023/11/01 \\
+ v0.6 & M. Boing & Firmware updates & 2024/03/14 \\
+ v1.0 & G. M. Marcelino, M. Boing & Stable release & 2024/09/05 \\
\bottomrule[1.5pt]
\end{tabular}
\end{center}
@@ -81,4 +84,4 @@
\end{center}
\end{figure}
-\textcopyright\ 2023 by SpaceLab. \thetitle. This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit \href{http://creativecommons.org/licenses/by-sa/4.0/}{http://creativecommons.org/licenses/by-sa/4.0/}.
\ No newline at end of file
+\textcopyright\ 2024 by SpaceLab. \thetitle. This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit \href{http://creativecommons.org/licenses/by-sa/4.0/}{http://creativecommons.org/licenses/by-sa/4.0/}.
diff --git a/doc/user_manual/header/titlepage.tex b/doc/user_manual/header/titlepage.tex
index f1f22266..10b6549f 100644
--- a/doc/user_manual/header/titlepage.tex
+++ b/doc/user_manual/header/titlepage.tex
@@ -15,7 +15,7 @@
%
% \author Gabriel Mariano Marcelino
%
-% \version 0.5.0
+% \version 1.0.0
%
% \date 2021/04/01
%
@@ -25,7 +25,7 @@
\thispagestyle{empty}
\begin{flushleft}
-SLB-TTC2-DOC-v0.5
+SLB-TTC2-DOC-v1.0
\end{flushleft}
\vspace{1cm}
@@ -52,7 +52,7 @@
\vfill
\begin{flushright}
-November 2023
+September 2024
\end{flushright}
-\end{titlepage}
\ No newline at end of file
+\end{titlepage}
diff --git a/doc/user_manual/main.tex b/doc/user_manual/main.tex
index 512965f3..e6f961bd 100644
--- a/doc/user_manual/main.tex
+++ b/doc/user_manual/main.tex
@@ -15,7 +15,7 @@
%
% \author Gabriel Mariano Marcelino
%
-% \version 0.3.0
+% \version 1.0.0
%
% \date 2021/04/01
%
@@ -54,6 +54,33 @@
\listoftables
\addcontentsline{toc}{chapter}{List of Tables}
+%----------- Nomenclature List ---------------
+\nomenclature{\textbf{PCB}}{\textit{Printed Circuit Board.}}
+\nomenclature{\textbf{GOLDS}}{\textit{Global Open coLlecting Data System.}}
+\nomenclature{\textbf{UFSC}}{\textit{Universidade Federal de Santa Catarina.}}
+\nomenclature{\textbf{RAM}}{\textit{Random Access Memory.}}
+\nomenclature{\textbf{RF}}{\textit{Radio Frequency.}}
+\nomenclature{\textbf{SRAM}}{\textit{Static Random Access Memory.}}
+\nomenclature{\textbf{GFSK}}{\textit{Gaussian Frequency Shift Keying.}}
+\nomenclature{\textbf{GMSK}}{\textit{Gaussian Minimum Shift Keying.}}
+\nomenclature{\textbf{NGHam}}{\textit{Next Generation Ham Radio.}}
+\nomenclature{\textbf{UART}}{\textit{Universal Asynchronous Receiver / Transmitter.}}
+\nomenclature{\textbf{SPI}}{\textit{Serial Peripheral Interface.}}
+\nomenclature{\textbf{HAL}}{\textit{Hardware Abstraction Layer.}}
+\nomenclature{\textbf{I$^2$C}}{\textit{Inter-Integrated Circuit.}}
+\nomenclature{\textbf{RTOS}}{\textit{Real Time Operating System.}}
+\nomenclature{\textbf{OBDH}}{\textit{On-Board Data Handling.}}
+\nomenclature{\textbf{EPS}}{\textit{Electric Power System.}}
+\nomenclature{\textbf{uC}}{\textit{MicroController.}}
+\nomenclature{\textbf{FEC}}{\textit{Forward Error Correction.}}
+\nomenclature{\textbf{RS}}{\textit{Reed-Solomon.}}
+\nomenclature{\textbf{JTAG}}{\textit{Joint Test Action Group.}}
+\nomenclature{\textbf{SDR}}{\textit{Software-Defined Radio.}}
+\nomenclature{\textbf{EM}}{\textit{Engineering Model.}}
+\nomenclature{\textbf{FM}}{\textit{Flight Model.}}
+\nomenclature{\textbf{TTC}}{\textit{Telemetry, Tracking and Command.}}
+%-----------------------------------------
+
\printnomenclature
\addcontentsline{toc}{chapter}{Nomenclature}
@@ -67,7 +94,8 @@
\input{chapters/hardware}
\input{chapters/firmware}
\input{chapters/operation}
+ \input{chapters/assembly}
\input{chapters/references}
- \input{appendices/appendices}
+% \input{appendices/appendices}
-\end{document}
\ No newline at end of file
+\end{document}
diff --git a/doc/user_manual/references/ccs-studio.bib b/doc/user_manual/references/ccs-studio.bib
new file mode 100644
index 00000000..f9298db1
--- /dev/null
+++ b/doc/user_manual/references/ccs-studio.bib
@@ -0,0 +1,6 @@
+@misc{ccs-studio,
+ author = {{Texas Instruments}},
+ title = {{Code Composer Studio™ integrated development environment (IDE)}},
+ year = {2024},
+ note = {Available at <\url{https://www.ti.com/tool/CCSTUDIO}>}
+}
diff --git a/doc/user_manual/references/marcelino2023.bib b/doc/user_manual/references/marcelino2023.bib
new file mode 100644
index 00000000..179948be
--- /dev/null
+++ b/doc/user_manual/references/marcelino2023.bib
@@ -0,0 +1,11 @@
+@article{marcelino2023,
+ author = {Marcelino, Gabriel Mariano and de Mattos, André Martins Pio and Barcellos, João Cláudio Elsen and Ribeiro, Brenda Fernandes and Seman, Laio Oriel and Filho, Edemar Morsch and Bezerra, Eduardo Augusto},
+ journal = {IEEE Embedded Systems Letters},
+ title = {FloripaSat-2: An Open-Source Platform for CubeSats},
+ year = {2024},
+ volume = {16},
+ number = {1},
+ pages = {77-80},
+ keywords = {Payloads;CubeSat;Protocols;Solar panels;Satellite broadcasting;Earth;Batteries;CubeSat;nanosatellite;open-source;service platform},
+ doi = {10.1109/LES.2023.3260066}
+}
diff --git a/doc/user_manual/references/sl-decoder.bib b/doc/user_manual/references/sl-decoder.bib
new file mode 100644
index 00000000..024dbb8b
--- /dev/null
+++ b/doc/user_manual/references/sl-decoder.bib
@@ -0,0 +1,6 @@
+@misc{sl-decoder,
+ author = {{SpaceLab}},
+ title = {{SpaceLab Decoder}},
+ year = {2024},
+ note = {Available at <\url{https://github.com/spacelab-ufsc/spacelab-decoder}>}
+}
diff --git a/doc/user_manual/references/sl-transmitter.bib b/doc/user_manual/references/sl-transmitter.bib
new file mode 100644
index 00000000..cddc2e30
--- /dev/null
+++ b/doc/user_manual/references/sl-transmitter.bib
@@ -0,0 +1,6 @@
+@misc{sl-transmitter,
+ author = {{SpaceLab}},
+ title = {{SpaceLab Transmitter}},
+ year = {2024},
+ note = {Available at <\url{https://github.com/spacelab-ufsc/spacelab-transmitter}>}
+}
diff --git a/doc/user_manual/references/ttc2-releases.bib b/doc/user_manual/references/ttc2-releases.bib
new file mode 100644
index 00000000..f0793531
--- /dev/null
+++ b/doc/user_manual/references/ttc2-releases.bib
@@ -0,0 +1,6 @@
+@misc{ttc2-releases,
+ author = {{SpaceLab}},
+ title = {{TTC 2.0 - Releases GitHub page}},
+ year = {2024},
+ note = {Available at <\url{https://github.com/spacelab-ufsc/ttc2/releases}>}
+}
diff --git a/doc/user_manual/slb-ttc2-doc-v0.5.pdf b/doc/user_manual/slb-ttc2-doc-v0.5.pdf
deleted file mode 100644
index c1a74b6c..00000000
Binary files a/doc/user_manual/slb-ttc2-doc-v0.5.pdf and /dev/null differ
diff --git a/firmware/.cproject b/firmware/.cproject
index cf1dda38..a1b9112e 100644
--- a/firmware/.cproject
+++ b/firmware/.cproject
@@ -15,38 +15,36 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -127,64 +160,64 @@
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/firmware/CHANGELOG b/firmware/CHANGELOG
index 64eb843f..a210c69b 100644
--- a/firmware/CHANGELOG
+++ b/firmware/CHANGELOG
@@ -1,3 +1,23 @@
+v1.0 - 2024/09/09
+
+- si446x improvements
+- RX implementation
+- OBDH device and server improvements
+- NGHam decoder implementation
+- Improvements for spi_slave
+- Fixes for Time control task
+- Adding reset command
+- Reset counter implementation
+- Fixing temperature sensors bugs
+- Fixes for flash driver
+- Improvements for media device
+- Flash mutex implementation
+- Firmware fix for LED label bug
+- Updates for unitary tests
+- General fixes and improvements
+
+===========================================
+
v0.5 - 2023/11/01
- Improving ttc struct
diff --git a/firmware/app/libs/ngham-0.1/CMakeLists.txt b/firmware/app/libs/ngham-0.1/CMakeLists.txt
deleted file mode 100644
index 6ca51ee3..00000000
--- a/firmware/app/libs/ngham-0.1/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-cmake_minimum_required(VERSION 3.0)
-
-# Disable in-source builds to prevent source tree corruption.
-if(" ${CMAKE_SOURCE_DIR}" STREQUAL " ${CMAKE_BINARY_DIR}")
- message(FATAL_ERROR "FATAL: In-source builds are not allowed. You should create a separate directory for build files.")
-endif()
-
-project(ngham C)
-
-include_directories(${CMAKE_SOURCE_DIR}/include)
-
-add_library(ngham STATIC ${CMAKE_SOURCE_DIR}/src/ngham.c)
-add_library(crc_ccitt STATIC ${CMAKE_SOURCE_DIR}/src/crc_ccitt.c)
-
-install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include)
-install(TARGETS ngham DESTINATION lib)
diff --git a/firmware/app/libs/ngham-0.1/include/ngham/ngham_extension.h b/firmware/app/libs/ngham-0.1/include/ngham/ngham_extension.h
deleted file mode 100644
index 943c20eb..00000000
--- a/firmware/app/libs/ngham-0.1/include/ngham/ngham_extension.h
+++ /dev/null
@@ -1,92 +0,0 @@
-//**************************************************************//
-// NGHam protocol - Jon Petter Skagmo, LA3JPA, 2014. //
-// Licensed under LGPL. //
-//**************************************************************//
-
-#ifndef NGHAM_EXTENSIONS_H
-#define NGHAM_EXTENSIONS_H
-
-#include "stdint.h"
-#include "ngham_packets.h"
-
-// Possible values for the type field. After type byte, length follows.
-#define PKT_TYPE_DATA 0
-#define PKT_TYPE_ID 1
-#define PKT_TYPE_STAT 2
-#define PKT_TYPE_SIMPLEDIGI 3
-#define PKT_TYPE_POS 4
-#define PKT_TYPE_TOH 5
-#define PKT_TYPE_DEST 6 // Destination/receiver callsign
-#define PKT_TYPE_CMD_REQ 7 // Command packet
-#define PKT_TYPE_CMD_REPLY 8 // Command packet
-#define PKT_TYPE_REQUEST 9
-
-#define PKT_TYPES 10
-#define PKT_SIZE_VARIABLE 0xffff
-
-extern const char* PKT_TYPE_STRINGS[];
-extern const uint16_t PKT_TYPE_SIZES[];
-
-// Additional NA-values
-#define TEMP_NA 0xff
-#define VOLT_NA 0xff
-#define UINT8_NA 0xff
-#define INT32_NA 0x7fffffff
-#define COG_NA 0x7ff
-
-// Ensure compatibility when used with MinGW etc.
-#ifdef _WIN32
-#define ATTRIBUTE_PACKED __attribute__ ((packed,gcc_struct))
-#else
-#define ATTRIBUTE_PACKED __attribute__ ((packed))
-#endif
-
-// TOH packet
-typedef struct ATTRIBUTE_PACKED{
- uint32_t toh_us; // Time of hour in microseconds
- uint8_t toh_val; // Validity
-}ngham_toh_t;
-
-// Statistics packet
-typedef struct ATTRIBUTE_PACKED{
- uint16_t hw_ver; // 10b company, 6b product
- uint16_t serial; // Serial nr.
- uint16_t sw_ver; // 4b major, 4b minor, 8b build
- uint32_t uptime_s; // Time in whole seconds since startup
- uint8_t voltage; // Input voltage in desivolts (0-25.5)
- int8_t temp; // System temp in deg. celsius (-128 to 127)
- uint8_t signal; // Received signal strength in dBm - 200, -200 to 54 (0xff=N/A)
- uint8_t noise; // Noise floor, same as above
- uint16_t cntr_rx_ok; // Packets successfully received
- uint16_t cntr_rx_fix; // Packets with corrected errors
- uint16_t cntr_rx_err; // Packets with uncorrectable errors
- uint16_t cntr_tx; // Packets sent
-}ngham_stat_t;
-
-// Position packet
-typedef struct ATTRIBUTE_PACKED{
- int32_t latitude; // In degrees * 10^7
- int32_t longitude; // In degrees * 10^7
- int32_t altitude; // In centimeters
- unsigned int sog:20; // Hundreds of meters per second
- unsigned int cog:12; // Tenths of degrees
- uint8_t hdop; // In tenths
-}ngham_pos_t;
-
-// Always first in a packet, except when resent by another station.
-typedef struct ATTRIBUTE_PACKED{
- uint8_t call_ssid[6]; // 7 x 6 bit (SIXBIT DEC, which is ASCII-32 and limited to 0-64) empty characters padded with 0, 6 bit SSID
- uint8_t sequence; // Wraps around from 255 to 0
-}ngham_id_t;
-
-typedef struct ATTRIBUTE_PACKED{
- uint8_t call_ssid[6]; // 7 x 6 bit (SIXBIT DEC, which is ASCII-32 and limited to 0-64) empty characters padded with 0, 6 bit SSID
-}ngham_dest_t;
-
-uint8_t* ngh_ext_allocate_pkt(tx_pkt_t* p, uint8_t pkt_type, uint16_t data_len);
-void ngh_ext_append_pkt(tx_pkt_t* p, uint8_t type, uint8_t* data, uint16_t size);
-uint16_t ngh_ext_numpkts(uint8_t* d, uint16_t d_len);
-uint8_t ngh_ext_encode_callsign(uint8_t* enc_callsign, char* callsign);
-void ngh_ext_decode_callsign(char* callsign, uint8_t* enc_callsign);
-
-#endif
\ No newline at end of file
diff --git a/firmware/app/libs/ngham-0.1/include/ngham/ngham_spp.h b/firmware/app/libs/ngham-0.1/include/ngham/ngham_spp.h
deleted file mode 100644
index b839cccc..00000000
--- a/firmware/app/libs/ngham-0.1/include/ngham/ngham_spp.h
+++ /dev/null
@@ -1,21 +0,0 @@
-//**************************************************************//
-// NGHam protocol - Jon Petter Skagmo, LA3JPA, 2014. //
-// Licensed under LGPL. //
-//**************************************************************//
-
-#include
-
-#include "ngham_packets.h"
-#include "ngham_paths.h"
-#include PATH_NGHAM_PLATFORM_SPP
-
-#define NGHAM_SPP_TYPE_RX 0x00 // Packet types
-#define NGHAM_SPP_TYPE_TX 0x01 // Packet types
-#define NGHAM_SPP_TYPE_LOCAL 0x02
-#define NGHAM_SPP_TYPE_CMD 0x03
-
-void ngham_parse_byte(port_ctx_t* ctx, uint8_t c);
-void ngham_spp_fill_header(ngh_spphdr_t* hdr, uint8_t type, uint8_t* d, uint16_t d_len);
-void ngham_print_cmd(port_ctx_t* ctx, uint8_t* d, uint16_t d_len);
-void ngham_print_rx_pkt(rx_pkt_t* p);
-void ngham_pack_tx_pkt_local(tx_pkt_t* p);
\ No newline at end of file
diff --git a/firmware/app/libs/ngham-0.1/src/ngham.c b/firmware/app/libs/ngham-0.1/src/ngham.c
deleted file mode 100755
index 6768e321..00000000
--- a/firmware/app/libs/ngham-0.1/src/ngham.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * ngham.c
- *
- * Copyright The NGHam Contributors.
- *
- * This file is part of NGHam.
- *
- * NGHam is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * NGHam is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with NGHam. If not, see .
- *
- */
-
-/**
- * \brief NGHam library implementation.
- *
- * \author Gabriel Mariano Marcelino
- *
- * \version 0.1.0
- *
- * \date 2023/03/12
- *
- * \addtogroup ngham
- * \{
- */
-
-#include /* For NULL etc. */
-#include /* For memcpy */
-#include /* For free */
-
-#include
-
-#include
-#include
-
-#include /* Pre-generated array from scrambling polynomial */
-#include
-
-/* There are seven different sizes. */
-/* Each size has a correlation tag for size, a total size, a maximum payload size and a parity data size. */
-#define NGH_SIZES 7
-
-/* Decoder states */
-#define NGH_STATE_SIZE_TAG 0
-#define NGH_STATE_SIZE_TAG_2 1
-#define NGH_STATE_SIZE_TAG_3 2
-#define NGH_STATE_SIZE_KNOWN 3
-#define NGH_STATE_STATUS 4
-#define NGH_STATE_STATUS_2 5
-
-/* Maximum number of errors in the size tag */
-#define NGH_SIZE_TAG_MAX_ERROR 6
-
-uint8_t NGH_PL_SIZE[7] = {28U, 60U, 92U, 124U, 156U, 188U, 220U}; /* Actual payload */
-uint8_t NGH_PL_SIZE_FULL[7] = {31U, 63U, 95U, 127U, 159U, 191U, 223U}; /* Size with LEN, payload and CRC */
-uint8_t NGH_PL_PAR_SIZE[7] = {47U, 79U, 111U, 159U, 191U, 223U, 255U}; /* Size with RS parity added */
-uint8_t NGH_PAR_SIZE[7] = {16U, 16U, 16U, 32U, 32U, 32U, 32U};
-
-/* The seven different size tag vectors */
-uint32_t NGH_SIZE_TAG[7] = {
- 0b001110110100100111001101,
- 0b010011011101101001010111,
- 0b011101101001001110011010,
- 0b100110111011010010101110,
- 0b101000001111110101100011,
- 0b110101100110111011111001,
- 0b111011010010011100110100
-};
-
-/* Preamble and synchronization vector */
-uint8_t NGH_PREAMBLE = 0xAAU;
-uint8_t NGH_PREAMBLE_FOUR_LEVEL = 0xDDU;
-uint8_t NGH_SYNC[4] = {0x5DU, 0xE6U, 0x2AU, 0x7EU};
-uint8_t NGH_SYNC_FOUR_LEVEL[8] = {0x77U, 0xF7U, 0xFDU, 0x7DU, 0x5DU, 0xDDU, 0x7FU, 0xFDU};
-
-/* Reed Solomon control blocks for the different NGHAM sizes */
-reed_solomon_t rs[NGH_SIZES] = {0};
-
-int decoder_state = NGH_STATE_SIZE_TAG;
-
-/**
- * \brief Generates the Reed-Solomon tables for all packets sizes.
- *
- * Run only once - generates Reed Solomon tables for all 7 packet sizes.
- *
- * MM=8, genpoly=0x187, fcs=112, prim=11, nroots=32 or 16
- *
- * \return The status/error code.
- */
-int ngham_init_arrays(void);
-
-/**
- * \brief Used to check if hamming distance in size tag is smaller than treshold.
- *
- * \param[in] x .
- *
- * \param[in] y .
- *
- * \return .
- */
-uint8_t ngham_tag_check(uint32_t x, uint32_t y);
-
-int ngham_init(void)
-{
- decoder_state = NGH_STATE_SIZE_TAG;
-
- return ngham_init_arrays();
-}
-
-int ngham_encode(uint8_t *data, uint16_t len, uint8_t flags, uint8_t *pkt, uint16_t *pkt_len)
-{
- uint16_t j = 0U;
- uint16_t crc = 0U;
- uint8_t size_nr = 0U;
- uint16_t d_len = 0U;
- uint8_t codeword_start = 0U;
-
- /* Check size and find control block for smallest possible RS codeword */
- if ((len == 0) || (len > NGH_PL_SIZE[NGH_SIZES - 1]))
- {
- return -1;
- }
-
- while(len > NGH_PL_SIZE[size_nr])
- {
- size_nr++;
- }
-
- /* Insert preamble, sync and size-tag */
- if (NGHAM_FOUR_LEVEL_MODULATION)
- {
- codeword_start = NGH_PREAMBLE_SIZE_FOUR_LEVEL + NGH_SYNC_SIZE_FOUR_LEVEL + NGH_SIZE_TAG_SIZE;
-
- for(j = 0; j < NGH_PREAMBLE_SIZE_FOUR_LEVEL; j++)
- {
- pkt[d_len++] = NGH_PREAMBLE_FOUR_LEVEL;
- }
-
- for(j = 0; j < NGH_SYNC_SIZE_FOUR_LEVEL; j++)
- {
- pkt[d_len++] = NGH_SYNC_FOUR_LEVEL[j];
- }
- }
- else
- {
- codeword_start = NGH_PREAMBLE_SIZE + NGH_SYNC_SIZE + NGH_SIZE_TAG_SIZE;
-
- for(j = 0U; j < NGH_PREAMBLE_SIZE; j++)
- {
- pkt[d_len++] = NGH_PREAMBLE;
- }
-
- for(j = 0U; j < NGH_SYNC_SIZE; j++)
- {
- pkt[d_len++] = NGH_SYNC[j];
- }
- }
-
- pkt[d_len++] = (NGH_SIZE_TAG[size_nr] >> 16) & 0xFFU;
- pkt[d_len++] = (NGH_SIZE_TAG[size_nr] >> 8) & 0xFFU;
- pkt[d_len++] = NGH_SIZE_TAG[size_nr] & 0xFFU;
-
- /* Prepare content of codeword */
- pkt[d_len] = (NGH_PL_SIZE[size_nr] - len) & 0x1FU; /* Insert padding size */
- pkt[d_len] |= (flags << 5) & 0xE0U; /* Insert flags */
- d_len++;
- for(j = 0; j < len; j++)
- {
- pkt[d_len++] = data[j]; /* Insert data */
- }
- crc = crc_ccitt(&pkt[codeword_start], len + 1); /* Insert CRC */
- pkt[d_len++] = (crc >> 8) & 0xFFU;
- pkt[d_len++] = crc & 0xFFU;
- for(j = len + 3; j < NGH_PL_SIZE_FULL[size_nr]; j++)
- {
- pkt[d_len++] = 0; /* Insert padding */
- }
-
- /* Generate parity data */
- uint8_t par_len = UINT8_MAX;
- rsc_encode(&rs[size_nr], &pkt[codeword_start], &pkt[d_len], &par_len);
- d_len += NGH_PAR_SIZE[size_nr];
-
- /* Scramble */
- for(j = 0; j < NGH_PL_PAR_SIZE[size_nr]; j++)
- {
- pkt[codeword_start + j] ^= ccsds_poly[j];
- }
-
- *pkt_len = d_len;
-
- return 0;
-}
-
-void ngham_decode(uint8_t d)
-{
-// static uint8_t size_nr;
-// static uint32_t size_tag;
-// static unsigned int length;
-// /* This points to the address one lower than the payload! */
-// static uint8_t* buf = (uint8_t*)&rx_pkt.ngham_flags;
-//
-// switch(decoder_state)
-// {
-// case NGH_STATE_SIZE_TAG:
-// size_tag = 0;
-// ngham_action_reception_started();
-// case NGH_STATE_SIZE_TAG_2:
-// size_tag <<= 8;
-// size_tag |= d;
-// decoder_state++;
-// break;
-// case NGH_STATE_SIZE_TAG_3:
-// size_tag <<= 8;
-// size_tag |= d;
-// {
-// for (size_nr = 0; size_nr < NGH_SIZES; size_nr++)
-// {
-// /* If tag is intact, set known size */
-// if (ngham_tag_check(size_tag, NGH_SIZE_TAG[size_nr]))
-// {
-// decoder_state = NGH_STATE_SIZE_KNOWN;
-// length = 0;
-//
-// /* Set new packet size as soon as possible */
-//// ngham_action_set_packet_size(NGH_PL_PAR_SIZE[size_nr] + NGH_SIZE_TAG_SIZE);
-// break;
-// }
-// }
-// /* If size tag is not found, every size can theoretically be attempted */
-// if (decoder_state != NGH_STATE_SIZE_KNOWN)
-// {
-//// ngham_action_handle_packet(PKT_CONDITION_PREFAIL, NULL);
-// decoder_state = NGH_STATE_SIZE_TAG;
-// }
-// }
-// break;
-// case NGH_STATE_SIZE_KNOWN:
-// /* De-scramble byte and append to buffer */
-// buf[length] = d^ccsds_poly[length];
-// length++;
-//
-// /* Do whatever is necessary in this action */
-// if (length == NGHAM_BYTES_TILL_ACTION_HALFWAY)
-// {
-// ngham_action_reception_halfway();
-// }
-//
-// if (length == NGH_PL_PAR_SIZE[size_nr])
-// {
-// int8_t errors;
-//
-// /* Set packet size back to a large value */
-//// ngham_action_set_packet_size(255);
-// decoder_state = NGH_STATE_SIZE_TAG;
-//
-// /* Run Reed Solomon decoding, calculate packet length */
-// errors = decode_rs_char(&rs_cb[size_nr], buf, 0, 0);
-// rx_pkt.pl_len = NGH_PL_SIZE[size_nr] - (buf[0] & NGH_PADDING_bm);
-//
-// /* Check if the packet is decodeable and then if CRC is OK */
-// if ((errors != -1) &&
-// (crc_ccitt(buf, rx_pkt.pl_len + 1) == ((buf[rx_pkt.pl_len + 1] << 8) | buf[rx_pkt.pl_len + 2])) )
-// {
-// /* Copy remaining fields and pass on */
-// rx_pkt.errors = errors;
-// rx_pkt.ngham_flags = (buf[0] & NGH_FLAGS_bm) >> NGH_FLAGS_bp;
-// rx_pkt.noise = ngham_action_get_noise_floor();
-// rx_pkt.rssi = ngham_action_get_rssi();
-//// ngham_action_handle_packet(PKT_CONDITION_OK, &rx_pkt);
-// }
-// /* If packet decoding not was successful, count this as an error */
-// else
-// {
-//// ngham_action_handle_packet(PKT_CONDITION_FAIL, NULL);
-// }
-// }
-// break;
-// }
-}
-
-int ngham_init_arrays(void)
-{
- int err = 0;
- int j = 0;
-
- for(j = 0; j < 3; j++)
- {
- if (rsc_init(8, 0x187, 112, 11, 16, (NGH_PL_PAR_SIZE[6] - NGH_PL_PAR_SIZE[j]), &rs[j]) != 0)
- {
- err = -1;
- }
- }
-
- for(; j < NGH_SIZES; j++)
- {
- if (rsc_init(8, 0x187, 112, 11, 32, (NGH_PL_PAR_SIZE[6] - NGH_PL_PAR_SIZE[j]), &rs[j]) != 0)
- {
- err = -1;
- }
- }
-
- return err;
-}
-
-uint8_t ngham_tag_check(uint32_t x, uint32_t y)
-{
- uint8_t j = 0U;
- uint8_t distance = 0U;
- uint32_t diff = x ^ y;
- uint8_t res = 0;
-
- if (diff != 0U)
- {
- for(j = 0U; j < 24U; j++)
- {
- if (diff & 0x01U)
- {
- distance++;
- if (distance > NGH_SIZE_TAG_MAX_ERROR)
- {
- res = 0;
- break;
- }
- }
-
- diff >>= 1;
- }
- }
- else
- {
- res = 1;
- }
-
- return res;
-}
-
-/**< \} End of ngham group */
diff --git a/firmware/app/libs/ngham-0.1/src/ngham_extension.c b/firmware/app/libs/ngham-0.1/src/ngham_extension.c
deleted file mode 100644
index d4a6336b..00000000
--- a/firmware/app/libs/ngham-0.1/src/ngham_extension.c
+++ /dev/null
@@ -1,175 +0,0 @@
-//**************************************************************//
-// NGHam protocol - Jon Petter Skagmo, LA3JPA, 2014. //
-// Licensed under LGPL. //
-//**************************************************************//
-
-#include "ngham_extension.h"
-
-#include "ngham_packets.h"
-#include "stdint.h"
-#include
-#include
-
-const char* PKT_TYPE_STRINGS[] = {
- "data",
- "id",
- "stat",
- "sdigi",
- "pos",
- "toh",
- "dest",
- "cmd_req",
- "cmd_reply",
- "request"
-};
-
-const uint16_t PKT_TYPE_SIZES[] = {
- PKT_SIZE_VARIABLE,
- sizeof(ngham_id_t),
- sizeof(ngham_stat_t),
- 1,
- sizeof(ngham_pos_t),
- sizeof(ngham_toh_t),
- sizeof(ngham_dest_t),
- PKT_SIZE_VARIABLE,
- PKT_SIZE_VARIABLE,
- 1
-};
-
-//void ngh_ext_readout_example(uint8_t* d, uint16_t d_len){
-// uint16_t start = 0;
-// uint16_t j;
-// // ngham_extract_numpkts does necessary length check of each field
-// for (j=0; jsignal-200
-// }
-// break;
-// }
-// start += d[start+1] + 2; // next start
-// }
-//}
-
-// Will set data type and length and increase tx_pkt length to fit data,
-// then return pointer to beginning of data without actually copying any data
-uint8_t* ngh_ext_allocate_pkt(tx_pkt_t* p, uint8_t pkt_type, uint16_t data_len){
- if ( (p->pl_len + 2 + data_len) > NGHAM_PL_MAX ) return NULL;
- p->pl[p->pl_len] = pkt_type;
- p->pl[p->pl_len+1] = data_len;
- p->pl_len += 2 + data_len;
- return p->pl+p->pl_len-data_len;
-}
-
-// Append extension packet with given data, type and size to tx_pkt
-void ngh_ext_append_pkt(tx_pkt_t* p, uint8_t type, uint8_t* data, uint16_t size){
- if ( (p->pl_len + 2 + size) > NGHAM_PL_MAX ) return;
- p->pl[p->pl_len] = type;
- p->pl[p->pl_len+1] = size;
- memcpy(&p->pl[p->pl_len+2], data, size);
- p->pl_len += 2 + size;
-}
-
-// Returns number of sub packets and verifies them
-uint16_t ngh_ext_numpkts(uint8_t* d, uint16_t d_len){
- // Go through all sub packets
- uint16_t start, packets;
- start = 0;
- packets = 0;
-
- while( (d_len >= (start+2)) && (d_len >= (start+2+d[start+1])) ){
- // If PKT_TYPE is invalid valid or packet type does not have correct length
- if ( (d[start]>PKT_TYPES) ||
- ((PKT_TYPE_SIZES[d[start]] != PKT_SIZE_VARIABLE) &&
- (PKT_TYPE_SIZES[d[start]] != d[start+1])) ){
- return 0;
- }
- packets++;
- start += d[start+1] + 2; // next start
- }
- return packets;
-}
-
-uint8_t ngh_ext_encode_callsign(uint8_t* enc_callsign, char* callsign){
- uint32_t temp;
- uint8_t j, copy[7], ssid = 0;
-
- // Convert to DEC SIXBIT until length is 7, zero terminated, or dash (SSID start)
- for (j=0; (j<7) && callsign[j] && (callsign[j]!='-'); j++){
- // Lowercase converted to uppercase
- if((callsign[j] >= 0x61) && (callsign[j] <= 0x7a)) copy[j] = callsign[j]-64;
- else copy[j] = callsign[j]-32;
- }
- if (j<7) copy[j] = 0; // Zero terminate if preliminary end
-
- // Get SSID, if any
- if (callsign[j] == '-'){
- j++;
- // First number
- if ( (callsign[j] >= 0x30) && (callsign[j] <= 0x39) ) ssid += (callsign[j] - '0');
- else return 0;
- j++;
- // Second number
- if ( (callsign[j] >= 0x30) && (callsign[j] <= 0x39) ){
- ssid *= 10;
- ssid += (callsign[j] - '0');
- j++;
- }
- else if (callsign[j] != 0) return 0;
- }
-
- temp = ((copy[0]<<18)&0xfc0000) | ((copy[1]<<12)&0x3f000) | ((copy[2]<<6)&0xfc0) | (copy[3]&0x3f);
- enc_callsign[0] = (temp>>16) & 0xff;
- enc_callsign[1] = (temp>>8) & 0xff;
- enc_callsign[2] = temp & 0xff;
-
- temp = ((copy[4]<<18)&0xfc0000) | ((copy[5]<<12)&0x3f000) | ((copy[6]<<6)&0xfc0) | (ssid&0x3f);
- enc_callsign[3] = (temp>>16) & 0xff;
- enc_callsign[4] = (temp>>8) & 0xff;
- enc_callsign[5] = temp & 0xff;
-
- return 1;
-}
-
-// 11 long array (7 characters, dash, two decimals and termination)
-// Destination "callsign", source "enc_callsign"
-void ngh_ext_decode_callsign(char* callsign, uint8_t* enc_callsign){
- uint32_t temp;
- uint8_t j, ssid;
-
- temp = ((enc_callsign[0]<<16)&0xff0000) | ((enc_callsign[1]<<8)&0xff00) | (enc_callsign[2]&0xff);
- callsign[0] = (temp>>18) & 0x3f;
- callsign[1] = (temp>>12) & 0x3f;
- callsign[2] = (temp>>6) & 0x3f;
- callsign[3] = temp & 0x3f;
-
- temp = ((enc_callsign[3]<<16)&0xff0000) | ((enc_callsign[4]<<8)&0xff00) | (enc_callsign[5]&0xff);
- callsign[4] = (temp>>18) & 0x3f;
- callsign[5] = (temp>>12) & 0x3f;
- callsign[6] = (temp>>6) & 0x3f;
- callsign[7] = 0; // Zero terminate (needed if max length)
-
- // Find end of callsign and convert from DEC SIXBIT
- for (j=0; (j<7) && callsign[j]; j++) callsign[j] += 32;
-
- // If non-zero SSID
- ssid = temp & 0x3f;
- if (ssid){
- callsign[j++] = '-';
- if (ssid > 9){
- callsign[j++] = (ssid/10) + '0';
- ssid %= 10;
- }
- callsign[j++] = ssid + '0';
- callsign[j] = 0;
- }
-}
\ No newline at end of file
diff --git a/firmware/app/libs/ngham-0.1/src/ngham_spp.c b/firmware/app/libs/ngham-0.1/src/ngham_spp.c
deleted file mode 100644
index 42b6a246..00000000
--- a/firmware/app/libs/ngham-0.1/src/ngham_spp.c
+++ /dev/null
@@ -1,142 +0,0 @@
-//**************************************************************//
-// NGHam protocol - Jon Petter Skagmo, LA3JPA, 2014. //
-// Licensed under LGPL. //
-// This is made somewhat platform specific for the Owl VHF //
-// with serial port contexts, and is meant as an guidance. //
-//**************************************************************//
-
-#include "ngham_spp.h"
-#include "crc_ccitt.h"
-#include // For memcpy
-
-// Definition of port context port_ctx_t and port_* functions,
-// as well as packer_call which sends data to transmit chain
-#include "ngham_paths.h"
-#include PATH_NGHAM_PLATFORM_SPP
-
-// Packet start byte definition
-#define SPP_START 0x24
-
-// States
-#define SPP_STATE_START 0x00
-#define SPP_STATE_HEADER 0x01
-#define SPP_STATE_PAYLOAD 0x02
-
-void ngham_parse_byte(port_ctx_t* ctx, uint8_t c){
- switch(ctx->state){
- case SPP_STATE_START:
- if (c == SPP_START){
- ctx->state = SPP_STATE_HEADER; // Start found; go to next state
- ctx->d_ip = 1; // Starts at next first as SPP_START is already received
- }
- break;
-
- case SPP_STATE_HEADER:
- // Fill ctx->d with header - no check for size, as buffer is much larger than header (5B)
- ctx->d[ctx->d_ip++] = c;
-
- if (ctx->d_ip >= sizeof(ngh_spphdr_t)){
- // Target length in d_op
- ctx->d_op = sizeof(ngh_spphdr_t) + ((ngh_spphdr_t*)ctx->d)->pl_len;
- ctx->state = SPP_STATE_PAYLOAD;
- }
- break;
-
- case SPP_STATE_PAYLOAD:
- // Fill ctx->d with payload
- if (ctx->d_ip < PORT_BUF_SIZE) ctx->d[ctx->d_ip++] = c;
-
- // If received length has met target length (set in STATE_HEADER)
- if (ctx->d_ip >= ctx->d_op){
- ngh_spphdr_t* hdr = (ngh_spphdr_t*)ctx->d;
-
- if (crc_ccitt(ctx->d+3, ctx->d_ip-3) == hdr->crc){
- switch(hdr->pl_type){
-
- // Data to be sent
- case NGHAM_SPP_TYPE_TX:
- {
- tx_pkt_t p;
- tx_pkt_init(&p);
-
- // Set flags, length (excluding flag-byte) and copy data
- p.ngham_flags = ctx->d[sizeof(ngh_spphdr_t)];
- p.pl_len = hdr->pl_len-1;
- memcpy(p.pl, ctx->d+sizeof(ngh_spphdr_t)+1, p.pl_len);
-
- // Packer call define - this is where the TX-packets are sent
- packer_call(&p);
-
- // TODO: Generate response!
- }
- break;
-
- // Command
- case NGHAM_SPP_TYPE_CMD:
- {
- uint8_t rep[REPLY_SIZE]; // CMD can be longer than SPP_PL_MAX
- uint16_t rep_len = 0;
- cmd(ctx->d+sizeof(ngh_spphdr_t), hdr->pl_len, rep, &rep_len, REPLY_SIZE); // Run command
- ngham_print_cmd(ctx, rep, rep_len); // Send reply
- }
- break;
- }
- }
-
- ctx->state = SPP_STATE_START;
- }
- break;
- }
-}
-
-void ngham_spp_fill_header(ngh_spphdr_t* hdr, uint8_t type, uint8_t* d, uint16_t d_len){
- uint16_t j, crc;
-
- hdr->start = SPP_START;
- hdr->pl_type = type;
- hdr->pl_len = d_len;
-
- crc = crc_ccitt_byte(hdr->pl_type, 0xffff);
- crc = crc_ccitt_byte(hdr->pl_len, crc);
- for (j=0; jcrc = crc;
-}
-
-void ngham_print_cmd(port_ctx_t* ctx, uint8_t* d, uint16_t d_len){
- ngh_spphdr_t hdr;
- uint16_t shortened_len, offset = 0;
-
- // Split into multiple packets if necessary
- while (d_len){
- if (d_len > SPP_PL_MAX) shortened_len = SPP_PL_MAX;
- else shortened_len = d_len;
-
- ngham_spp_fill_header(&hdr, NGHAM_SPP_TYPE_CMD, d+offset, shortened_len);
-
- // Copy remaining and send to port
- port_output(ctx, (uint8_t*)&hdr, sizeof(ngh_spphdr_t));
- port_output(ctx, d+offset, hdr.pl_len);
-
- d_len -= shortened_len;
- offset += shortened_len;
- }
-}
-
-// Output buffer should be prefilled with
-void ngham_print_rx_pkt(rx_pkt_t* p){
- ngh_spphdr_t hdr;
-
- ngham_spp_fill_header(&hdr, NGHAM_SPP_TYPE_RX, (uint8_t*)p, p->pl_len+8);
- port_unpacker_output(PACKER_NGHAM, (uint8_t*)&hdr, sizeof(ngh_spphdr_t));
- port_unpacker_output(PACKER_NGHAM, (uint8_t*)p, hdr.pl_len);
-}
-
-void ngham_pack_tx_pkt_local(tx_pkt_t* p){
- ngh_spphdr_t hdr;
-
- ngham_spp_fill_header(&hdr, NGHAM_SPP_TYPE_LOCAL, (uint8_t*)&(p->ngham_flags), p->pl_len+1);
- port_unpacker_output(PACKER_NGHAM, (uint8_t*)&hdr, sizeof(ngh_spphdr_t));
- port_unpacker_output(PACKER_NGHAM, (uint8_t*)&(p->ngham_flags), hdr.pl_len);
-}
diff --git a/firmware/app/libs/ngham-0.1/tests/CMakeLists.txt b/firmware/app/libs/ngham-0.1/tests/CMakeLists.txt
deleted file mode 100644
index 08e6e2c9..00000000
--- a/firmware/app/libs/ngham-0.1/tests/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-cmake_minimum_required(VERSION 3.0)
-
-project(ngham_test C)
-
-include_directories(${CMAKE_SOURCE_DIR}/../include)
-
-add_library(ngham STATIC ${CMAKE_SOURCE_DIR}/../src/ngham.c)
-
-add_executable(ngham_test ${CMAKE_SOURCE_DIR}/test.c)
-
-target_link_libraries(ngham_test cmocka)
-target_link_libraries(ngham_test ngham)
diff --git a/firmware/app/libs/ngham-0.1/tests/Makefile b/firmware/app/libs/ngham-0.1/tests/Makefile
deleted file mode 100644
index 29049734..00000000
--- a/firmware/app/libs/ngham-0.1/tests/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-TARGET=ngham_unit_test
-
-ifndef BUILD_DIR
- BUILD_DIR=$(CURDIR)
-endif
-
-CC=gcc
-INC=../include
-FLAGS=-fpic -std=c99 -Wall -pedantic -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -I$(INC)
-
-.PHONY: all
-all: $(BUILD_DIR)/ccsds_scrambler.o $(BUILD_DIR)/crc_ccitt.o $(BUILD_DIR)/ngham.o $(BUILD_DIR)/test.o
- $(CC) $(FLAGS) $(BUILD_DIR)/ccsds_scrambler.o $(BUILD_DIR)/crc_ccitt.o $(BUILD_DIR)/ngham.o $(BUILD_DIR)/test.o -o $(BUILD_DIR)/$(TARGET) -lcmocka -lrsc
-
-$(BUILD_DIR)/ccsds_scrambler.o: ../src/ccsds_scrambler.c
- $(CC) $(FLAGS) -c $< -o $@
-
-$(BUILD_DIR)/crc_ccitt.o: ../src/crc_ccitt.c
- $(CC) $(FLAGS) -c $< -o $@
-
-$(BUILD_DIR)/ngham.o: ../src/ngham.c
- $(CC) $(FLAGS) -c $< -o $@
-
-$(BUILD_DIR)/test.o: test.c
- $(CC) $(FLAGS) -c $< -o $@
-
-.PHONY: clean
-clean:
- rm $(BUILD_DIR)/$(TARGET) $(BUILD_DIR)/*.o
diff --git a/firmware/app/libs/ngham-1.0/.github/workflows/static-anlysis.yml b/firmware/app/libs/ngham-1.0/.github/workflows/static-anlysis.yml
new file mode 100644
index 00000000..70ecee01
--- /dev/null
+++ b/firmware/app/libs/ngham-1.0/.github/workflows/static-anlysis.yml
@@ -0,0 +1,53 @@
+#
+# static-analysis.yml
+#
+# Copyright The NGHam Contributors.
+#
+# This file is part of NGHam.
+#
+# NGHam is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# NGHam is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with NGHam. If not, see .
+#
+#
+
+name: Static Analysis
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main, dev]
+
+ # 'workflow_dispatch' allows manual execution of this workflow under the repository's 'Actions' tab
+ workflow_dispatch:
+
+jobs:
+
+ cppcheck-analysis:
+ name: cppcheck-analysis
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: false
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Install CppCheck
+ run: sudo apt install -y cppcheck
+
+ - name: Execute CppCheck on header files
+ run: cppcheck --std=c99 --error-exitcode=-1 --addon=misra.py $PWD/include/ngham/*
+
+ - name: Execute CppCheck on source files
+ run: cppcheck --std=c99 --error-exitcode=-1 --addon=misra.py --inline-suppr -I$PWD/include/ngham/ -I$PWD/include/ $PWD/src/* --suppress=misra-c2012-8.4
\ No newline at end of file
diff --git a/firmware/app/libs/ngham-0.1/.github/workflows/test.yml b/firmware/app/libs/ngham-1.0/.github/workflows/test.yml
similarity index 77%
rename from firmware/app/libs/ngham-0.1/.github/workflows/test.yml
rename to firmware/app/libs/ngham-1.0/.github/workflows/test.yml
index 4cb87163..0d109459 100755
--- a/firmware/app/libs/ngham-0.1/.github/workflows/test.yml
+++ b/firmware/app/libs/ngham-1.0/.github/workflows/test.yml
@@ -24,7 +24,7 @@ name: Unit tests
on:
push:
- branches: [dev]
+ branches: [main]
pull_request:
branches: [main, dev]
@@ -42,22 +42,21 @@ jobs:
steps:
- uses: actions/checkout@v3
+ with:
+ submodules: true
+
- name: Install dependencies
run: |
sudo apt install -y cmake libcmocka0 libcmocka-dev
- git clone https://github.com/mgm8/rsclib.git
- cd rsclib
- mkdir build
- cd build
- cmake ..
- make
- sudo make install
+ mkdir firmware/app/libs/ngham-1.0/tests/build_tests
+ cd firmware/app/libs/ngham-1.0/tests/build_tests
+ cmake ../
- name: Compile the test
run: |
- cd tests
- make
+ cd firmware/app/libs/ngham-1.0/tests/build_tests
+ cmake --build .
- name: Execute the test
- run: ./tests/ngham_unit_test
+ run: ./firmware/app/libs/ngham-1.0/tests/build_tests/ngham_test
diff --git a/firmware/app/libs/ngham-0.1/.gitignore b/firmware/app/libs/ngham-1.0/.gitignore
similarity index 100%
rename from firmware/app/libs/ngham-0.1/.gitignore
rename to firmware/app/libs/ngham-1.0/.gitignore
diff --git a/firmware/app/libs/ngham-1.0/.gitmodules b/firmware/app/libs/ngham-1.0/.gitmodules
new file mode 100644
index 00000000..fb2ca28f
--- /dev/null
+++ b/firmware/app/libs/ngham-1.0/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "rsclib"]
+ path = rsclib
+ url = https://github.com/miguelboing/rsclib
diff --git a/firmware/app/libs/ngham-1.0/CMakeLists.txt b/firmware/app/libs/ngham-1.0/CMakeLists.txt
new file mode 100644
index 00000000..e7b4c776
--- /dev/null
+++ b/firmware/app/libs/ngham-1.0/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.0)
+
+# Disable in-source builds to prevent source tree corruption.
+if(" ${CMAKE_SOURCE_DIR}" STREQUAL " ${CMAKE_BINARY_DIR}")
+ message(FATAL_ERROR "FATAL: In-source builds are not allowed. You should create a separate directory for build files.")
+endif()
+
+project(ngham C)
+
+add_subdirectory(rsclib)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/rsclib/include)
+
+
+add_library(ngham STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/ngham.c ${CMAKE_CURRENT_SOURCE_DIR}/src/ngham_packets.c ${CMAKE_CURRENT_SOURCE_DIR}/src/crc_ccitt.c ${CMAKE_CURRENT_SOURCE_DIR}/src/ccsds_scrambler.c ${CMAKE_CURRENT_SOURCE_DIR}/src/ngham_packets.c)
+
+install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include)
+install(TARGETS ngham DESTINATION lib)
diff --git a/firmware/app/libs/ngham-0.1/LICENSE b/firmware/app/libs/ngham-1.0/LICENSE
similarity index 100%
rename from firmware/app/libs/ngham-0.1/LICENSE
rename to firmware/app/libs/ngham-1.0/LICENSE
diff --git a/firmware/app/libs/ngham-0.1/README.md b/firmware/app/libs/ngham-1.0/README.md
similarity index 93%
rename from firmware/app/libs/ngham-0.1/README.md
rename to firmware/app/libs/ngham-1.0/README.md
index 44b6f067..b05b10ee 100644
--- a/firmware/app/libs/ngham-0.1/README.md
+++ b/firmware/app/libs/ngham-1.0/README.md
@@ -16,7 +16,6 @@ Main features:
[Youtube video: NGHam demonstration with Owl VHF and TDMA](http://youtu.be/_96td-Y-LLA)
-


@@ -42,6 +41,12 @@ Not finished:
|:----------- |:----------- |
| ngham_extension.h | An extension of the payload field in the NGHam radio protocol (enabled by a flag in the NGHam header). |
+Cloning
+This NGHam implementation uses a GitHub submodule. To successfully clone the repository, the ``--recurse-submodules`` flag is required.
+```
+git clone https://github.com/miguelboing/ngham.git --recurse-submodules
+```
+
Usage (for NGHam RF protocol):
1. Provide your own sync word correlator and GMSK (de)modulator.
diff --git a/firmware/app/libs/ngham-0.1/include/ngham/ccsds_scrambler.h b/firmware/app/libs/ngham-1.0/include/ngham/ccsds_scrambler.h
old mode 100755
new mode 100644
similarity index 89%
rename from firmware/app/libs/ngham-0.1/include/ngham/ccsds_scrambler.h
rename to firmware/app/libs/ngham-1.0/include/ngham/ccsds_scrambler.h
index aa4983d1..e504e3d6
--- a/firmware/app/libs/ngham-0.1/include/ngham/ccsds_scrambler.h
+++ b/firmware/app/libs/ngham-1.0/include/ngham/ccsds_scrambler.h
@@ -16,7 +16,7 @@
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
- * along with NGHam. If not, see .
+ * along with NGHam. If not, see .
*
*/
@@ -24,10 +24,11 @@
* \brief CCSDS scrambler definition.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
*
- * \version 0.0.0
+ * \version 1.0.0
*
- * \date 2023/03/12
+ * \date 2024/08/26
*
* \defgroup ccsds-scrambler CCSDS Scrambler
* \ingroup ngham
diff --git a/firmware/app/libs/ngham-0.1/include/ngham/config.h b/firmware/app/libs/ngham-1.0/include/ngham/config.h
similarity index 92%
rename from firmware/app/libs/ngham-0.1/include/ngham/config.h
rename to firmware/app/libs/ngham-1.0/include/ngham/config.h
index 5435d1c5..6db59557 100644
--- a/firmware/app/libs/ngham-0.1/include/ngham/config.h
+++ b/firmware/app/libs/ngham-1.0/include/ngham/config.h
@@ -24,10 +24,11 @@
* \brief Configuration parameters.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
*
- * \version 0.1.0
+ * \version 1.0.0
*
- * \date 2023/06/15
+ * \date 2024/08/26
*
* \defgroup config Configuration
* \ingroup ngham
diff --git a/firmware/app/libs/ngham-0.1/include/ngham/crc_ccitt.h b/firmware/app/libs/ngham-1.0/include/ngham/crc_ccitt.h
old mode 100755
new mode 100644
similarity index 90%
rename from firmware/app/libs/ngham-0.1/include/ngham/crc_ccitt.h
rename to firmware/app/libs/ngham-1.0/include/ngham/crc_ccitt.h
index 80cc8f8f..a9041183
--- a/firmware/app/libs/ngham-0.1/include/ngham/crc_ccitt.h
+++ b/firmware/app/libs/ngham-1.0/include/ngham/crc_ccitt.h
@@ -16,7 +16,7 @@
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
- * along with NGHam. If not, see .
+ * along with NGHam. If not, see .
*
*/
@@ -24,10 +24,11 @@
* \brief CRC-CCITT definition.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
*
- * \version 0.0.2
+ * \version 1.0.0
*
- * \date 2023/03/12
+ * \date 2024/08/26
*
* \defgroup crc-ccitt CRC-CCITT
* \ingroup ngham
diff --git a/firmware/app/libs/ngham-0.1/include/ngham/ngham.h b/firmware/app/libs/ngham-1.0/include/ngham/ngham.h
old mode 100755
new mode 100644
similarity index 76%
rename from firmware/app/libs/ngham-0.1/include/ngham/ngham.h
rename to firmware/app/libs/ngham-1.0/include/ngham/ngham.h
index a278a405..6204b646
--- a/firmware/app/libs/ngham-0.1/include/ngham/ngham.h
+++ b/firmware/app/libs/ngham-1.0/include/ngham/ngham.h
@@ -16,7 +16,7 @@
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
- * along with NGHam. If not, see .
+ * along with NGHam. If not, see .
*
*/
@@ -24,10 +24,11 @@
* \brief NGHam library definition.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
*
- * \version 0.1.0
+ * \version 1.0.0
*
- * \date 2023/03/12
+ * \date 2024/06/03
*
* \defgroup ngham NGHam
* \{
@@ -40,7 +41,7 @@
#include "ngham_packets.h"
-#define NGHAM_VERSION "v0.1.0"
+#define NGHAM_VERSION "v1.0.0"
#define NGH_PREAMBLE_SIZE 4U
#define NGH_SYNC_SIZE 4U
@@ -81,13 +82,21 @@ int ngham_init(void);
int ngham_encode(uint8_t *data, uint16_t len, uint8_t flags, uint8_t *pkt, uint16_t *pkt_len);
/**
- * \brief Decodes a given NGHam packet to data.
+ * \brief Encodes a given data into a NGHam packet.
+ *
+ * Received packets are passed to this function - max. length 512B.
+ *
+ * \param[in] pkt is the array of bytes to be decoded.
*
- * \param[in] d .
+ * \param[in] pkt_len is number of bytes of the packet.
*
- * \return None.
+ * \param[in,out] data is a pointer to store the decoded packet.
+ *
+ * \param[in,out] data_len is the number of bytes of the decoded packet.
+ *
+ * \return The status/error code.
*/
-void ngham_decode(uint8_t d);
+int ngham_decode(uint8_t* pkt, uint16_t pkt_len, uint8_t* data, uint16_t* data_len);
#endif /* NGHAM_H_ */
diff --git a/firmware/app/libs/ngham-1.0/include/ngham/ngham_extension.h b/firmware/app/libs/ngham-1.0/include/ngham/ngham_extension.h
new file mode 100644
index 00000000..6ef72e27
--- /dev/null
+++ b/firmware/app/libs/ngham-1.0/include/ngham/ngham_extension.h
@@ -0,0 +1,9 @@
+//**************************************************************//
+// NGHam protocol - Jon Petter Skagmo, LA3JPA, 2014. //
+// Licensed under LGPL. //
+//**************************************************************//
+
+#ifndef NGHAM_EXTENSIONS_H
+#define NGHAM_EXTENSIONS_H
+
+#endif
diff --git a/firmware/app/libs/ngham-0.1/include/ngham/ngham_packets.h b/firmware/app/libs/ngham-1.0/include/ngham/ngham_packets.h
similarity index 77%
rename from firmware/app/libs/ngham-0.1/include/ngham/ngham_packets.h
rename to firmware/app/libs/ngham-1.0/include/ngham/ngham_packets.h
index fb1401ec..c6439fff 100644
--- a/firmware/app/libs/ngham-0.1/include/ngham/ngham_packets.h
+++ b/firmware/app/libs/ngham-1.0/include/ngham/ngham_packets.h
@@ -8,11 +8,6 @@
#include "stdint.h"
-// Possible packet conditions
-#define PKT_CONDITION_OK 0 // Successfully received packet
-#define PKT_CONDITION_FAIL 1 // Receiption failed after receiving the packet
-#define PKT_CONDITION_PREFAIL 2 // Reception failed before receiving the whole packet
-
// Packet priority in transmission
#define PKT_PRIORITY_NORMAL 0
#define PKT_PRIORITY_FIRST_IN_SLOT 10 // Should be put first in the next time slot for timing purposes
@@ -21,8 +16,8 @@
#define PKT_PL_SIZE 512
// Basic "not available"-values
-#define RSSI_NA 0xff
-#define TIMESTAMP_NA 0xffffffff
+#define RSSI_NA 0xffU
+#define TIMESTAMP_NA 0xffffffffU
// If the following flag is set in a packet, NGHam extensions are used and first byte is type
#define NGHAM_FLAG_TYPE_EXTENSION 0x01
@@ -55,13 +50,6 @@ typedef struct ATTRIBUTE_PACKED{
uint16_t pl_len;
}tx_pkt_t;
-// NGHam SPP header
-typedef struct ATTRIBUTE_PACKED{
- uint8_t start;
- uint16_t crc;
- uint8_t pl_type;
- uint8_t pl_len;
-}ngh_spphdr_t;
void rx_pkt_init(rx_pkt_t *p);
void tx_pkt_init(tx_pkt_t *p);
diff --git a/firmware/app/libs/ngham-1.0/include/ngham/ngham_spp.h b/firmware/app/libs/ngham-1.0/include/ngham/ngham_spp.h
new file mode 100644
index 00000000..e55031ed
--- /dev/null
+++ b/firmware/app/libs/ngham-1.0/include/ngham/ngham_spp.h
@@ -0,0 +1,21 @@
+// //**************************************************************//
+// // NGHam protocol - Jon Petter Skagmo, LA3JPA, 2014. //
+// // Licensed under LGPL. //
+// //**************************************************************//
+
+// #include
+
+// #include "ngham_packets.h"
+// //#include "ngham_paths.h"
+// #include PATH_NGHAM_PLATFORM_SPP
+
+// #define NGHAM_SPP_TYPE_RX 0x00 // Packet types
+// #define NGHAM_SPP_TYPE_TX 0x01 // Packet types
+// #define NGHAM_SPP_TYPE_LOCAL 0x02
+// #define NGHAM_SPP_TYPE_CMD 0x03
+
+// void ngham_parse_byte(port_ctx_t* ctx, uint8_t c);
+// void ngham_spp_fill_header(ngh_spphdr_t* hdr, uint8_t type, uint8_t* d, uint16_t d_len);
+// void ngham_print_cmd(port_ctx_t* ctx, uint8_t* d, uint16_t d_len);
+// void ngham_print_rx_pkt(rx_pkt_t* p);
+// void ngham_pack_tx_pkt_local(tx_pkt_t* p);
\ No newline at end of file
diff --git a/firmware/app/libs/ngham-1.0/rsclib/.github/workflows/static-analysis.yml b/firmware/app/libs/ngham-1.0/rsclib/.github/workflows/static-analysis.yml
new file mode 100644
index 00000000..e20aade8
--- /dev/null
+++ b/firmware/app/libs/ngham-1.0/rsclib/.github/workflows/static-analysis.yml
@@ -0,0 +1,53 @@
+#
+# static-analysis.yml
+#
+# Copyright The RSCLib Contributors.
+#
+# This file is part of RSCLib.
+#
+# RSCLib is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RSCLib is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with RSCLib. If not, see .
+#
+#
+
+name: Static Analysis
+
+on:
+ push:
+ branches: [dev]
+ pull_request:
+ branches: [main, dev]
+
+ # 'workflow_dispatch' allows manual execution of this workflow under the repository's 'Actions' tab
+ workflow_dispatch:
+
+jobs:
+
+ cppcheck-analysis:
+ name: cppcheck-analysis
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: false
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Install CppCheck
+ run: sudo apt install -y cppcheck
+
+ - name: Execute CppCheck on header files
+ run: cppcheck --std=c99 --error-exitcode=-1 --addon=misra.py $PWD/firmware/app/libs/ngham-1.0/rsclib/include/rsc/*
+
+ - name: Execute CppCheck on source files
+ run: cppcheck --std=c99 --error-exitcode=-1 --addon=misra.py -I$PWD/firmware/app/libs/ngham-1.0/rsclib/include/ $PWD/firmware/app/libs/ngham-1.0/rsclib/src/*
diff --git a/firmware/app/libs/rsclib-0.1/.github/workflows/test.yml b/firmware/app/libs/ngham-1.0/rsclib/.github/workflows/test.yml
similarity index 91%
rename from firmware/app/libs/rsclib-0.1/.github/workflows/test.yml
rename to firmware/app/libs/ngham-1.0/rsclib/.github/workflows/test.yml
index e84755b5..7046bf22 100644
--- a/firmware/app/libs/rsclib-0.1/.github/workflows/test.yml
+++ b/firmware/app/libs/ngham-1.0/rsclib/.github/workflows/test.yml
@@ -48,9 +48,9 @@ jobs:
- name: Compile the test
run: |
- cd tests
+ cd firmware/app/libs/ngham-1.0/rsclib/tests
cmake .
make
- name: Execute the test
- run: ./tests/rsc_test
+ run: ./firmware/app/libs/ngham-1.0/rsclib/tests/rsc_test
diff --git a/firmware/app/libs/rsclib-0.1/.gitignore b/firmware/app/libs/ngham-1.0/rsclib/.gitignore
similarity index 100%
rename from firmware/app/libs/rsclib-0.1/.gitignore
rename to firmware/app/libs/ngham-1.0/rsclib/.gitignore
diff --git a/firmware/app/libs/rsclib-0.1/CMakeLists.txt b/firmware/app/libs/ngham-1.0/rsclib/CMakeLists.txt
similarity index 57%
rename from firmware/app/libs/rsclib-0.1/CMakeLists.txt
rename to firmware/app/libs/ngham-1.0/rsclib/CMakeLists.txt
index d25c52d9..3358e454 100644
--- a/firmware/app/libs/rsclib-0.1/CMakeLists.txt
+++ b/firmware/app/libs/ngham-1.0/rsclib/CMakeLists.txt
@@ -5,11 +5,11 @@ if(" ${CMAKE_SOURCE_DIR}" STREQUAL " ${CMAKE_BINARY_DIR}")
message(FATAL_ERROR "FATAL: In-source builds are not allowed. You should create a separate directory for build files.")
endif()
-project(rsc LANGUAGES C VERSION 0.1.0 HOMEPAGE_URL https://github.com/mgm8/rsclib)
+project(rsc LANGUAGES C VERSION 1.0.1 HOMEPAGE_URL https://github.com/mgm8/rsclib)
-include_directories(${CMAKE_SOURCE_DIR}/include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
-add_library(rsc STATIC ${CMAKE_SOURCE_DIR}/src/rsc.c)
+add_library(rsc STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/rsc.c)
-install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include)
+install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include)
install(TARGETS rsc DESTINATION lib)
diff --git a/firmware/app/libs/rsclib-0.1/LICENSE b/firmware/app/libs/ngham-1.0/rsclib/LICENSE
similarity index 100%
rename from firmware/app/libs/rsclib-0.1/LICENSE
rename to firmware/app/libs/ngham-1.0/rsclib/LICENSE
diff --git a/firmware/app/libs/rsclib-0.1/README.md b/firmware/app/libs/ngham-1.0/rsclib/README.md
similarity index 87%
rename from firmware/app/libs/rsclib-0.1/README.md
rename to firmware/app/libs/ngham-1.0/rsclib/README.md
index 3c2c6c90..4a9446e5 100644
--- a/firmware/app/libs/rsclib-0.1/README.md
+++ b/firmware/app/libs/ngham-1.0/rsclib/README.md
@@ -4,7 +4,7 @@
-
+
## Overview
diff --git a/firmware/app/libs/rsclib-0.1/include/rsc/rsc.h b/firmware/app/libs/ngham-1.0/rsclib/include/rsc/rsc.h
similarity index 75%
rename from firmware/app/libs/rsclib-0.1/include/rsc/rsc.h
rename to firmware/app/libs/ngham-1.0/rsclib/include/rsc/rsc.h
index 68edd00d..7132a11e 100644
--- a/firmware/app/libs/rsclib-0.1/include/rsc/rsc.h
+++ b/firmware/app/libs/ngham-1.0/rsclib/include/rsc/rsc.h
@@ -16,7 +16,7 @@
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
- * along with RSCLib. If not, see .
+ * along with RSCLib. If not, see .
*
*/
@@ -24,10 +24,11 @@
* \brief Reed-Solomon C library definition.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
+ *
+ * \version 1.0.1
*
- * \version 0.1.0
- *
- * \date 2022/03/06
+ * \date 2024/05/09
*
* \defgroup rsclib Reed Solomon C Library
* \{
@@ -38,23 +39,23 @@
#include
-#define RSC_VERSION "v0.1.0"
+#define RSC_VERSION "v1.0.1"
/**
* \brief Reed-Solomon codec control block.
*/
typedef struct
{
- int mm; /**< Bits per symbol */
- int nn; /**< Symbols per block (= (1 << mm) - 1) */
+ uint32_t mm; /**< Bits per symbol */
+ uint32_t nn; /**< Symbols per block (= (1 << mm) - 1) */
uint8_t alpha_to[256]; /**< log lookup table */
uint8_t index_of[256]; /**< Antilog lookup table */
uint8_t genpoly[64]; /**< Generator polynomial */
- int nroots; /**< Number of generator roots = number of parity symbols */
- int fcr; /**< First consecutive root, index form */
- int prim; /**< Primitive element, index form */
- int iprim; /**< prim-th root of 1, index form */
- int pad; /**< Padding bytes in shortened block */
+ uint32_t nroots; /**< Number of generator roots = number of parity symbols */
+ uint32_t fcr; /**< First consecutive root, index form */
+ uint32_t prim; /**< Primitive element, index form */
+ uint32_t iprim; /**< prim-th root of 1, index form */
+ uint32_t pad; /**< Padding bytes in shortened block */
} reed_solomon_t;
/**
@@ -76,7 +77,7 @@ typedef struct
*
* \return The status/error code.
*/
-int rsc_init(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad, reed_solomon_t *rs);
+int rsc_init(uint32_t symsize, int gfpoly, uint32_t fcr, uint32_t prim, uint32_t nroots, uint32_t pad, reed_solomon_t *rs);
/**
* \brief Computes the parity data of a given byte sequence.
@@ -108,7 +109,7 @@ void rsc_encode(reed_solomon_t *rs, uint8_t *data, uint8_t *parity, uint8_t *par
*
* \return The status/error code.
*/
-int rsc_decode(reed_solomon_t *rs, uint8_t *pkt, uint8_t *data, uint8_t *err_pos, uint8_t *num_err);
+int rsc_decode(reed_solomon_t *rs, uint8_t *data, int *err_pos, int *num_err);
#endif /* RSC_H_ */
diff --git a/firmware/app/libs/ngham-1.0/rsclib/src/rsc.c b/firmware/app/libs/ngham-1.0/rsclib/src/rsc.c
new file mode 100644
index 00000000..9808f872
--- /dev/null
+++ b/firmware/app/libs/ngham-1.0/rsclib/src/rsc.c
@@ -0,0 +1,515 @@
+/*
+ * rsc.c
+ *
+ * Copyright The RSCLib Contributors.
+ *
+ * This file is part of RSCLib.
+ *
+ * RSCLib is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * RSCLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with RSCLib. If not, see .
+ *
+ */
+
+/**
+ * \brief Reed-Solomon C library implementation.
+ *
+ * \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
+ *
+ * \version 1.0.1
+ *
+ * \date 2024/05/09
+ *
+ * \addtogroup rsclib
+ * \{
+ */
+
+#include
+#include "rsc/rsc.h"
+
+/**
+ * \brief Computes the modulo of a given number.
+ *
+ * \param[in] rs is the Reed-Solomon scheme used to compute the modulo.
+ *
+ * \param[in] x is the integer to compute the modulo.
+ *
+ * \return The computed modulo value of the given number.
+ */
+
+static int modnn(reed_solomon_t *rs, int num);
+
+static int min(int a, int b);
+
+int rsc_init(uint32_t symsize, int gfpoly, uint32_t fcr, uint32_t prim, uint32_t nroots, uint32_t pad, reed_solomon_t *rs)
+{
+ int err = 0;
+
+ uint32_t i;
+ uint32_t j;
+ uint32_t sr;
+ uint32_t root;
+ uint32_t iprim;
+
+ /* Check parameter ranges */
+ if (symsize <= (8U * sizeof(uint8_t)))
+ {
+ if (fcr < (1UL << symsize))
+ {
+ if ((prim > 0U) && ( prim < (1U << symsize)))
+ {
+ if (( nroots < (1U << symsize)))
+ {
+ if ((pad < ((1U << symsize) - 1U - nroots)))
+ {
+ rs->mm = symsize;
+ rs->nn = (1U << symsize) - 1U;
+ rs->pad = pad;
+
+ /* Generate Galois field lookup tables */
+ rs->index_of[0] = rs->nn; /* log(zero) = -inf */
+ rs->alpha_to[rs->nn] = 0; /* alpha**-inf = 0 */
+ sr = 1U;
+ for(i = 0; i < rs->nn; i++)
+ {
+ rs->index_of[sr] = i;
+ rs->alpha_to[i] = sr;
+ sr <<= 1;
+ if ((sr & (1U << symsize)) != 0U)
+ {
+ sr ^= gfpoly;
+ }
+ sr &= rs->nn;
+ }
+ if (sr == 1U)
+ {
+ rs->fcr = fcr;
+ rs->prim = prim;
+ rs->nroots = nroots;
+
+ /* Find prim-th root of 1, used in decoding */
+ for(iprim = 1U; (iprim % prim) != 0U; iprim += rs->nn)
+ {
+ }
+ rs->iprim = iprim / prim;
+
+ rs->genpoly[0] = 1U;
+
+ root = fcr * prim;
+ for(i = 0U; i < nroots; i++)
+ {
+ if (i != 0U)
+ {
+ root += prim;
+ }
+
+ rs->genpoly[i + 1U] = 1U;
+
+ /* Multiply rs->genpoly[] by @**(root + x) */
+ for(j = i; j > 0U; j--)
+ {
+ if (rs->genpoly[j] != 0U)
+ {
+ rs->genpoly[j] = rs->genpoly[j - 1U] ^ rs->alpha_to[modnn(rs, rs->index_of[rs->genpoly[j]] + (uint32_t)root)];
+ }
+ else
+ {
+ rs->genpoly[j] = rs->genpoly[j - 1U];
+ }
+ }
+ /* rs->genpoly[0] can never be zero */
+ rs->genpoly[0] = rs->alpha_to[modnn(rs, rs->index_of[rs->genpoly[0]] + (uint32_t)root)];
+ }
+ /* convert rs->genpoly[] to index form for quicker encoding */
+ for(i = 0U; i <= nroots; i++)
+ {
+ rs->genpoly[i] = rs->index_of[rs->genpoly[i]];
+ }
+
+ err = 0;
+ }
+ else
+ {
+ /* field generator polynomial is not primitive! */
+ (void)memset(rs, 0, sizeof(reed_solomon_t));
+
+ err = -1;
+ }
+ }
+ else
+ {
+ err = 0; /* Too much padding */
+ }
+ }
+ else
+ {
+ err = -1; /* Can't have more roots than symbol values! */
+ }
+ }
+ else
+ {
+ err = -1;
+ }
+ }
+ else
+ {
+ err = -1;
+ }
+ }
+ else
+ {
+ err = -1;
+ }
+
+ return err;
+}
+
+void rsc_encode(reed_solomon_t *rs, uint8_t *data, uint8_t *parity, uint8_t *parity_len)
+{
+ uint32_t i = 0;
+ uint32_t j = 0;
+ uint32_t feedback = 0;
+
+ (void)memset(parity, 0, rs->nroots);
+
+ for(i = 0U; i < (rs->nn - rs->nroots - rs->pad); i++)
+ {
+ feedback = rs->index_of[data[i] ^ parity[0]];
+ if (feedback != rs->nn) /* feedback term is non-zero */
+ {
+ for(j = 0U; j < rs->nroots; j++)
+ {
+ parity[j] ^= rs->alpha_to[modnn(rs, feedback + rs->genpoly[rs->nroots - j])];
+ }
+ }
+ /* Shift */
+ (void)memmove(&parity[0], &parity[1], rs->nroots - 1U);
+ if (feedback != rs->nn)
+ {
+ parity[rs->nroots - 1U] = rs->alpha_to[modnn(rs, feedback + rs->genpoly[0])];
+ }
+ else
+ {
+ parity[rs->nroots - 1U] = 0U;
+ }
+ }
+
+ *parity_len = rs->nroots;
+}
+
+int rsc_decode(reed_solomon_t *rs, uint8_t *data, int *err_pos, int *num_err)
+{
+ int err = -1;
+
+ int deg_lambda = 0;
+ int el = 0;
+ int deg_omega = 0;
+
+ int r = 0;
+ int i = 0;
+ int j = 0;
+ int k = 0;
+
+ uint8_t u = 0;
+ uint8_t q = 0;
+ uint8_t tmp = 0;
+ uint8_t num1 = 0;
+ uint8_t num2 = 0;
+ uint8_t den = 0;
+ uint8_t discr_r = 0;
+ uint8_t lambda[33] = {0};
+ uint8_t s[32] = {0};
+ uint8_t b[33] = {0};
+ uint8_t t[33] = {0};
+ uint8_t omega[33] = {0};
+ uint8_t root[32] = {0};
+ uint8_t reg[33] = {0};
+ uint8_t loc[32] = {0};
+
+ int syn_error = 0;
+ int count = 0;
+
+ /* Form the syndromes; i.e., evaluate data(x) at roots of g(x) */
+ for (i=0;i<(int)rs->nroots;i++)
+ {
+ s[i] = data[0];
+ }
+
+ for(j = 1; j < ((int)(rs->nn) - (int)(rs->pad)); j++)
+ {
+ for(i = 0; i < (int)rs->nroots; i++)
+ {
+ if (s[i] == 0U)
+ {
+ s[i] = data[j];
+ }
+ else
+ {
+ s[i] = data[j] ^ rs->alpha_to[modnn(rs, ((int)(rs->index_of[s[i]]) + ((int)(rs->fcr) + i) * (int)(rs->prim)))];
+ }
+ }
+ }
+
+ for(i = 0; i < (int)rs->nroots; i++)
+ {
+ syn_error |= s[i];
+ s[i] = rs->index_of[s[i]];
+
+ }
+
+
+ if (syn_error == 0)
+ {
+ /* if syndrome is zero, data[] is a codeword and there are no errors
+ to correct. So return data[] unmodified */
+ count = 0;
+ err = 0;
+ }
+ else
+ {
+ (void)memset(&lambda[1],0,rs->nroots*sizeof(lambda[0]));
+ lambda[0] = 1U;
+
+ if (*num_err > 0)
+ {
+ /* Init lambda to be the erasure locator polynomial */
+ lambda[1] = rs->alpha_to[modnn(rs, rs->prim * (rs->nn - 1U - (uint32_t)(err_pos[0])))];
+ for(i = 1U; i < *num_err; i++)
+ {
+ u = modnn(rs, rs->prim * (rs->nn - 1U - (uint32_t)(err_pos[i])));
+ for(j = i + 1; j > 0; j--)
+ {
+ tmp = rs->index_of[lambda[j - 1]];
+ if (tmp != rs->nn)
+ {
+ lambda[j] ^= rs->alpha_to[modnn(rs, u + tmp)];
+ }
+ }
+ }
+ }
+
+ for(i = 0; i < ((int)(rs->nroots) + 1); i++)
+ {
+ b[i] = rs->index_of[lambda[i]];
+ }
+
+ /* Begin Berlekamp-Massey algorithm to determine error+erasure locator polynomial */
+ r = *num_err;
+ el = *num_err;
+ while(++r <= rs->nroots) /* r is the step number */
+ {
+ /* Compute discrepancy at the r-th step in poly-form */
+ discr_r = 0;
+ for(i = 0U; i < r; i++)
+ {
+ if ((lambda[i] != 0U) && ((uint32_t)(s[r - i - 1]) != rs->nn))
+ {
+ discr_r ^= rs->alpha_to[modnn(rs, rs->index_of[lambda[i]] + s[r - i - 1])];
+ }
+ }
+ discr_r = rs->index_of[discr_r]; /* Index form */
+ if ((uint32_t)discr_r == rs->nn)
+ {
+ /* 2 lines below: B(x) <-- x*B(x) */
+ (void)memmove(&b[1],b,rs->nroots*sizeof(b[0]));
+ b[0] = (uint8_t) rs->nn;
+ }
+ else
+ {
+ /* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
+ t[0] = lambda[0];
+ for(i = 0U; i < (int) rs->nroots; i++)
+ {
+ if (((uint32_t) b[i]) != rs->nn)
+ {
+ t[i + 1] = lambda[i + 1] ^ rs->alpha_to[modnn(rs, discr_r + b[i])];
+ }
+ else
+ {
+ t[i + 1] = lambda[i + 1];
+ }
+ }
+ if ((2 * el) <= (r + *num_err - 1))
+ {
+ el = r + *num_err - el;
+ /* 2 lines below: B(x) <-- inv(discr_r) * lambda(x) */
+ for(i = 0; i <= (int)rs->nroots; i++)
+ {
+ if (lambda[i] == 0U)
+ {
+ b[i] = (uint8_t)rs->nn;
+ }
+ else
+ {
+ b[i] = modnn(rs, rs->index_of[lambda[i]] - discr_r + rs->nn);
+ }
+ }
+ }
+ else
+ {
+ /* 2 lines below: B(x) <-- x*B(x) */
+ (void)memmove(&b[1],b,(rs->nroots)*sizeof(b[0]));
+ b[0] = 255U;
+ }
+
+ (void)memcpy(lambda,t,(rs->nroots)*sizeof(t[0]));
+ }
+ }
+
+ /* Convert lambda to index form and compute deg(lambda(x)) */
+ deg_lambda = 0;
+
+ for(i = 0; i < ((int)(rs->nroots) + 1); i++)
+ {
+ lambda[i] = rs->index_of[lambda[i]];
+ if (lambda[i] != rs->nn)
+ {
+ deg_lambda = i;
+ }
+ }
+ /* Find roots of the error+erasure locator polynomial by Chien search */
+ (void)memcpy(®[1],&lambda[1],rs->nroots*sizeof(reg[0]));
+ count = 0; /* Number of roots of lambda(x) */
+ k =(int)(rs->iprim) - 1;
+ for(i = 1; i <= (int)(rs->nn); i++)
+ {
+ if (i != 1)
+ {
+ k = modnn(rs, k + (int)(rs->iprim));
+ }
+
+ q = 1; /* lambda[0] is always 0 */
+ for(j = deg_lambda; j > 0; j--)
+ {
+ if (reg[j] != rs->nn)
+ {
+ reg[j] = modnn(rs, reg[j] + (uint8_t)j);
+ q ^= rs->alpha_to[reg[j]];
+ }
+ }
+
+ if (q != 0U)
+ {
+ continue; /* Not a root */
+ }
+ /* store root (index-form) and error location number */
+ root[count] = i;
+ loc[count] = k;
+ /* If we've already found max possible roots, abort the search to save time */
+ if (++count == deg_lambda)
+ {
+ break;
+ }
+
+ }
+ if (deg_lambda != count)
+ {
+ /* deg(lambda) unequal to number of roots => uncorrectable error detected */
+ count = -1;
+ err = -1;
+ }
+ else
+ {
+ /* Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo x**rs.nroots). in index form. Also find deg(omega) */
+ deg_omega = deg_lambda - 1;
+ for(i = 0; i <= deg_omega; i++)
+ {
+ tmp = 0;
+ for(j = i; j >= 0; j--)
+ {
+ if ((s[i - j] != rs->nn) && (lambda[j] != rs->nn))
+ {
+ tmp ^= rs->alpha_to[modnn(rs, s[i - j] + lambda[j])];
+ }
+ }
+ omega[i] = rs->index_of[tmp];
+ }
+
+ /* Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = inv(X(l))**(rs.fcr-1) and den = lambda_pr(inv(X(l))) all in poly-form */
+ for(j = (count - 1); j >= 0; j--)
+ {
+ num1 = 0;
+ for(i = deg_omega; i >= 0; i--)
+ {
+ if (omega[i] != rs->nn)
+ {
+ num1 ^= rs->alpha_to[modnn(rs, (int)omega[i] + (i * (int)root[j]))];
+ }
+ }
+ num2 = rs->alpha_to[modnn(rs, (int)(root[j]) * ((int)(rs->fcr) - 1) + (int)(rs->nn))];
+ den = 0;
+
+ /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
+ for (i = min(deg_lambda, ((int)(rs->nroots)-1)) & ~1; i>=0; i -= 2)
+ {
+ if (lambda[i + 1] != rs->nn)
+ {
+ den ^= rs->alpha_to[modnn(rs, (int)lambda[i + 1] + (i * (int)root[j]))];
+ }
+ }
+ /* Apply error to data */
+ if ((num1 != 0U) && (loc[j] >= rs->pad))
+ {
+ data[loc[j] - rs->pad] ^= rs->alpha_to[modnn(rs, rs->index_of[num1] + rs->index_of[num2] + rs->nn - rs->index_of[den])];
+ }
+ }
+ err = 0;
+ }
+ }
+
+ if (err_pos != NULL)
+ {
+ for(i = 0; i < count; i++)
+ {
+ err_pos[i] = loc[i];
+ }
+ }
+
+ if (num_err != NULL)
+ {
+ *num_err = count;
+ }
+
+ return err;
+}
+
+static int modnn(reed_solomon_t *rs, int num)
+{
+ uint32_t x;
+ x = (uint32_t)num;
+
+ while(x >= rs->nn)
+ {
+ x -= rs->nn;
+ x = (x >> rs->mm) + (x & rs->nn);
+ }
+
+ return (int)x;
+}
+
+static int min(int a, int b)
+{
+ int min;
+ if (a <= b)
+ {
+ min = a;
+ }
+ else
+ {
+ min = b;
+ }
+
+ return min;
+}
+
+/**< \} End of rsclib group */
diff --git a/firmware/app/libs/rsclib-0.1/tests/.gitignore b/firmware/app/libs/ngham-1.0/rsclib/tests/.gitignore
similarity index 100%
rename from firmware/app/libs/rsclib-0.1/tests/.gitignore
rename to firmware/app/libs/ngham-1.0/rsclib/tests/.gitignore
diff --git a/firmware/app/libs/rsclib-0.1/tests/CMakeLists.txt b/firmware/app/libs/ngham-1.0/rsclib/tests/CMakeLists.txt
similarity index 100%
rename from firmware/app/libs/rsclib-0.1/tests/CMakeLists.txt
rename to firmware/app/libs/ngham-1.0/rsclib/tests/CMakeLists.txt
diff --git a/firmware/app/libs/rsclib-0.1/tests/README.md b/firmware/app/libs/ngham-1.0/rsclib/tests/README.md
similarity index 100%
rename from firmware/app/libs/rsclib-0.1/tests/README.md
rename to firmware/app/libs/ngham-1.0/rsclib/tests/README.md
diff --git a/firmware/app/libs/rsclib-0.1/tests/test.c b/firmware/app/libs/ngham-1.0/rsclib/tests/test.c
similarity index 55%
rename from firmware/app/libs/rsclib-0.1/tests/test.c
rename to firmware/app/libs/ngham-1.0/rsclib/tests/test.c
index ffc41ce8..3576157c 100644
--- a/firmware/app/libs/rsclib-0.1/tests/test.c
+++ b/firmware/app/libs/ngham-1.0/rsclib/tests/test.c
@@ -24,10 +24,11 @@
* \brief Reed-Solomon C library unit test.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
+ *
+ * \version 1.0.1
*
- * \version 0.1.0
- *
- * \date 2022/05/30
+ * \date 2024/04/30
*
* \defgroup test Test
* \ingroup rsclib
@@ -37,13 +38,20 @@
#include
#include
#include
+#include
+#include
+#include
+#include
#include
#include
#include
#include
+#include
#include
+uint8_t random_value(uint8_t min, uint8_t max);
+
static void rsc_init_test(void **state)
{
reed_solomon_t rs16 = {0};
@@ -94,40 +102,84 @@ static void rsc_encode_test(void **state)
static void rsc_decode_test(void **state)
{
-// reed_solomon_t rs16 = {0};
-//
-// rsc_init(8, 0x187, 112, 11, 16, 208, &rs16);
-//
-// uint8_t data[32] = {0U};
-// uint8_t par[32] = {0U};
-// uint8_t par_len = 0U;
-// uint8_t pkt[300] = {0U};
-//
-// uint8_t i = 0;
-//
-// for(i = 0; i < 32; i++)
-// {
-// data[i] = i;
-// }
-//
-// rsc_encode(&rs16, data, par, &par_len);
-//
-// /* Merge data and parity */
-// memcpy(pkt, data, 32);
-// memcpy(&pkt[32], par, par_len);
-//
-// uint8_t dec_data[32] = {0U};
-// uint8_t err_pos[32] = {0U};
-// uint8_t num_err = 0U;
-//
-// assert_return_code(rsc_decode(&rs16, pkt, dec_data, err_pos, &num_err), 0);
-//
-// assert_memory_equal(dec_data, data, 32);
-// assert_int_equal(num_err, 0);
-}
+ reed_solomon_t rs = {0};
+ int rs_padding, rs_msg_size, rs_nroots;
+
+ uint8_t data[255] = {0U};
+ uint8_t par[255] = {0U};
+ uint8_t par_len = 0U;
+ uint8_t pkt[300] = {0U};
+ int err_pos[255] = {0U};
+ int expected_err_pos[255] = {0U};
+ int num_err = 0U;
+ int s_err = 0U;
+ int s_exp_err = 0U;
+ uint8_t rand_number_of_errors;
+ bool rand_error_pos_arr[255];
+ uint8_t rand_error_position;
+ uint8_t rand_error_value;
+
+ rs_nroots = (int) (random_value(1,2)) * 16;
+
+ rs_msg_size = random_value(1,255 - (uint8_t)rs_nroots);
+ rs_padding = 255 - rs_msg_size - (uint8_t)rs_nroots;
+
+ rsc_init(8, 0x187, 112, 11, rs_nroots, rs_padding, &rs);
+
+ uint8_t i,j = 0;
+ for(i=0;i.
+ * along with NGHam. If not, see .
*
*/
@@ -24,10 +24,11 @@
* \brief CCSDS scrambler implementation.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
*
- * \version 0.1.0
+ * \version 1.0.0
*
- * \date 2023/03/12
+ * \date 2024/08/26
*
* \addtogroup ccsds_scrambler
* \{
@@ -62,7 +63,7 @@ const uint8_t ccsds_poly[255] = {0xFF, 0x48, 0x0E, 0xC0, 0x9A, 0x0D, 0x70, 0xBC,
uint8_t ccsds_poly_pos = 0U;
-void ccsds_scrambler_init()
+void ccsds_scrambler_init(void)
{
ccsds_poly_pos = 0U;
}
diff --git a/firmware/app/libs/ngham-0.1/src/crc_ccitt.c b/firmware/app/libs/ngham-1.0/src/crc_ccitt.c
old mode 100755
new mode 100644
similarity index 96%
rename from firmware/app/libs/ngham-0.1/src/crc_ccitt.c
rename to firmware/app/libs/ngham-1.0/src/crc_ccitt.c
index fd1e82f8..68c0eaa9
--- a/firmware/app/libs/ngham-0.1/src/crc_ccitt.c
+++ b/firmware/app/libs/ngham-1.0/src/crc_ccitt.c
@@ -16,7 +16,7 @@
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
- * along with NGHam. If not, see .
+ * along with NGHam. If not, see .
*
*/
@@ -24,10 +24,11 @@
* \brief implementation.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
*
- * \version 0.0.2
+ * \version 1.0.0
*
- * \date 2023/03/12
+ * \date 2024/08/26
*
* \addtogroup crc_ccitt
* \{
diff --git a/firmware/app/libs/ngham-1.0/src/ngham.c b/firmware/app/libs/ngham-1.0/src/ngham.c
new file mode 100644
index 00000000..1a83158f
--- /dev/null
+++ b/firmware/app/libs/ngham-1.0/src/ngham.c
@@ -0,0 +1,388 @@
+/*
+ * ngham.c
+ *
+ * Copyright The NGHam Contributors.
+ *
+ * This file is part of NGHam.
+ *
+ * NGHam is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NGHam is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NGHam. If not, see .
+ *
+ */
+
+/**
+ * \brief NGHam library implementation.
+ *
+ * \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/06/03
+ *
+ * \addtogroup ngham
+ * \{
+ */
+
+#include /* For NULL etc. */
+#include /* For memcpy */
+#include /* For free */
+#include
+
+#include "ngham/ngham.h"
+#include "ngham/config.h"
+
+#include "ngham/ccsds_scrambler.h" /* Pre-generated array from scrambling polynomial */
+#include "ngham/crc_ccitt.h"
+
+/* There are seven different sizes. */
+/* Each size has a correlation tag for size, a total size, a maximum payload size and a parity data size. */
+#define NGH_SIZES 7U
+
+/* Decoder states */
+#define NGH_STATE_SIZE_TAG 0
+#define NGH_STATE_SIZE_TAG_2 1
+#define NGH_STATE_SIZE_TAG_3 2
+#define NGH_STATE_SIZE_KNOWN 3
+#define NGH_STATE_STATUS 4
+#define NGH_STATE_STATUS_2 5
+
+/* Maximum number of errors in the size tag */
+#define NGH_SIZE_TAG_MAX_ERROR 6U
+
+uint8_t NGH_PL_SIZE[7] = {28U, 60U, 92U, 124U, 156U, 188U, 220U}; /* Actual payload */
+uint8_t NGH_PL_SIZE_FULL[7] = {31U, 63U, 95U, 127U, 159U, 191U, 223U}; /* Size with LEN, payload and CRC */
+uint8_t NGH_PL_PAR_SIZE[7] = {47U, 79U, 111U, 159U, 191U, 223U, 255U}; /* Size with RS parity added */
+uint8_t NGH_PAR_SIZE[7] = {16U, 16U, 16U, 32U, 32U, 32U, 32U};
+
+/* The seven different size tag vectors */
+uint32_t NGH_SIZE_TAG[7] = {
+ 0b001110110100100111001101,
+ 0b010011011101101001010111,
+ 0b011101101001001110011010,
+ 0b100110111011010010101110,
+ 0b101000001111110101100011,
+ 0b110101100110111011111001,
+ 0b111011010010011100110100
+};
+
+/* Preamble and synchronization vector */
+uint8_t NGH_PREAMBLE = 0xAAU;
+uint8_t NGH_PREAMBLE_FOUR_LEVEL = 0xDDU;
+uint8_t NGH_SYNC[4] = {0x5DU, 0xE6U, 0x2AU, 0x7EU};
+uint8_t NGH_SYNC_FOUR_LEVEL[8] = {0x77U, 0xF7U, 0xFDU, 0x7DU, 0x5DU, 0xDDU, 0x7FU, 0xFDU};
+
+/* Reed Solomon control blocks for the different NGHAM sizes */
+reed_solomon_t rs[NGH_SIZES] = {0};
+
+int decoder_state = NGH_STATE_SIZE_TAG;
+
+rx_pkt_t rx_pkt;
+
+/**
+ * \brief Generates the Reed-Solomon tables for all packets sizes.
+ *
+ * Run only once - generates Reed Solomon tables for all 7 packet sizes.
+ *
+ * MM=8, genpoly=0x187, fcs=112, prim=11, nroots=32 or 16
+ *
+ * \return The status/error code.
+ */
+static int ngham_init_arrays(void);
+
+/**
+ * \brief Used to check if hamming distance in size tag is smaller than threshold.
+ *
+ * \param[in] x .
+ *
+ * \param[in] y .
+ *
+ * \return .
+ */
+static uint8_t ngham_tag_check(uint32_t x, uint32_t y);
+
+static int ngham_decode_byte(uint8_t d, uint8_t* pkt);
+
+int ngham_init(void)
+{
+ decoder_state = NGH_STATE_SIZE_TAG;
+
+ return ngham_init_arrays();
+}
+
+int ngham_encode(uint8_t *data, uint16_t len, uint8_t flags, uint8_t *pkt, uint16_t *pkt_len)
+{
+ int err = -1;
+ uint16_t j = 0U;
+ uint16_t crc = 0U;
+ uint8_t size_nr = 0U;
+ uint16_t d_len = 0U;
+ uint8_t codeword_start = 0U;
+
+ /* Check size and find control block for smallest possible RS codeword */
+ if (!((len == 0U) || (len > NGH_PL_SIZE[NGH_SIZES - 1U])))
+ {
+ while(len > NGH_PL_SIZE[size_nr])
+ {
+ size_nr++;
+ }
+
+ /* Insert preamble, sync and size-tag */
+ if (NGHAM_FOUR_LEVEL_MODULATION == 1)
+ {
+ codeword_start = NGH_PREAMBLE_SIZE_FOUR_LEVEL + NGH_SYNC_SIZE_FOUR_LEVEL + NGH_SIZE_TAG_SIZE;
+
+ for(j = 0; j < NGH_PREAMBLE_SIZE_FOUR_LEVEL; j++)
+ {
+ pkt[d_len] = NGH_PREAMBLE_FOUR_LEVEL;
+ d_len++;
+ }
+
+ for(j = 0; j < NGH_SYNC_SIZE_FOUR_LEVEL; j++)
+ {
+ pkt[d_len] = NGH_SYNC_FOUR_LEVEL[j];
+ d_len++;
+ }
+ }
+ else
+ {
+ codeword_start = NGH_PREAMBLE_SIZE + NGH_SYNC_SIZE + NGH_SIZE_TAG_SIZE;
+
+ for(j = 0U; j < NGH_PREAMBLE_SIZE; j++)
+ {
+ pkt[d_len] = NGH_PREAMBLE;
+ d_len++;
+ }
+
+ for(j = 0U; j < NGH_SYNC_SIZE; j++)
+ {
+ pkt[d_len] = NGH_SYNC[j];
+ d_len++;
+ }
+ }
+
+ pkt[d_len] = (NGH_SIZE_TAG[size_nr] >> 16) & 0xFFU;
+ d_len++;
+ pkt[d_len] = (NGH_SIZE_TAG[size_nr] >> 8) & 0xFFU;
+ d_len++;
+ pkt[d_len] = NGH_SIZE_TAG[size_nr] & 0xFFU;
+ d_len++;
+
+ /* Prepare content of codeword */
+ pkt[d_len] = (NGH_PL_SIZE[size_nr] - len) & 0x1FU; /* Insert padding size */
+ pkt[d_len] |= (flags << 5) & 0xE0U; /* Insert flags */
+ d_len++;
+ for(j = 0; j < len; j++)
+ {
+ pkt[d_len] = data[j]; /* Insert data */
+ d_len++;
+ }
+ crc = crc_ccitt(&pkt[codeword_start], len + 1U); /* Insert CRC */
+ pkt[d_len] = (crc >> 8) & 0xFFU;
+ d_len++;
+ pkt[d_len] = crc & 0xFFU;
+ d_len++;
+ for(j = len + 3U; j < NGH_PL_SIZE_FULL[size_nr]; j++)
+ {
+ pkt[d_len] = 0; /* Insert padding */
+ d_len++;
+ }
+
+ /* Generate parity data */
+ uint8_t par_len = UINT8_MAX;
+ rsc_encode(&rs[size_nr], &pkt[codeword_start], &pkt[d_len], &par_len);
+ d_len += NGH_PAR_SIZE[size_nr];
+
+ /* Scramble */
+ for(j = 0; j < NGH_PL_PAR_SIZE[size_nr]; j++)
+ {
+ pkt[codeword_start + j] ^= ccsds_poly[j];
+ }
+
+ *pkt_len = d_len;
+ err = 0;
+ }
+ return err;
+}
+
+int ngham_decode(uint8_t* pkt, uint16_t pkt_len, uint8_t* data, uint16_t* data_len)
+{
+ int err = -1;
+ uint16_t i = 0U;
+ static uint8_t preamb_sync_1[8] = {0xAA, 0xAA, 0xAA, 0xAA, 0x5D, 0xE6, 0x2A, 0x7E};
+ static uint8_t preamb_sync_2[16] = {0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x77, 0xF7, 0xFD, 0x7D, 0x5D, 0xDD, 0x7F, 0xFD};
+ uint8_t offset = 0U;
+
+
+ /* Remove for preamble and sync*/
+ if (memcmp(preamb_sync_1, pkt, 8U * sizeof(pkt[0])) == 0)
+ {
+ offset = 8U;
+ }
+ else if(memcmp(preamb_sync_2, pkt, 16U * sizeof(pkt[0])) == 0)
+ {
+ offset = 16U;
+ }
+ else
+ {
+ offset = 0U;
+ }
+
+ rx_pkt_init(&rx_pkt);
+
+ for (i=offset; i < pkt_len; i++)
+ {
+ if (ngham_decode_byte(pkt[i], &pkt[offset + 3U]) == 0)
+ {
+ err = 0;
+ break;
+ }
+ }
+
+ (void)memcpy(data, rx_pkt.pl, rx_pkt.pl_len);
+ *data_len = rx_pkt.pl_len;
+
+ return err;
+}
+
+static int ngham_decode_byte(uint8_t d, uint8_t* buf)
+{
+ static uint8_t size_nr;
+ static uint32_t size_tag;
+ static unsigned int length;
+ int8_t errors;
+ uint32_t num_errors = 0U;
+ int err = -1;
+
+ switch(decoder_state)
+ {
+ case NGH_STATE_SIZE_TAG:
+ size_tag = 0U;
+ /* No break because fall-through is intended */
+
+ case NGH_STATE_SIZE_TAG_2: // cppcheck-suppress misra-c2012-16.3
+ size_tag <<= 8U;
+ size_tag |= d;
+ decoder_state++;
+ break;
+ case NGH_STATE_SIZE_TAG_3:
+ size_tag <<= 8U;
+ size_tag |= d;
+ {
+ for (size_nr = 0U; size_nr < NGH_SIZES; size_nr++)
+ {
+ /* If tag is intact, set known size */
+ if (ngham_tag_check(size_tag, NGH_SIZE_TAG[size_nr]) == 1U)
+ {
+ decoder_state = NGH_STATE_SIZE_KNOWN;
+ length = 0U;
+
+ break;
+ }
+ }
+ /* If size tag is not found, every size can theoretically be attempted */
+ if (decoder_state != NGH_STATE_SIZE_KNOWN)
+ {
+ decoder_state = NGH_STATE_SIZE_TAG;
+ }
+ }
+ break;
+ case NGH_STATE_SIZE_KNOWN:
+ /* De-scramble byte and append to buffer */
+ buf[length] = d^ccsds_poly[length];
+ length++;
+
+ if (length == NGH_PL_PAR_SIZE[size_nr])
+ {
+ decoder_state = NGH_STATE_SIZE_TAG;
+
+ errors = rsc_decode(&rs[size_nr], buf, 0UL, &num_errors);
+ rx_pkt.pl_len = NGH_PL_SIZE[size_nr] - (buf[0] & NGH_PADDING_bm);
+
+ /* Check if the packet is decodeable and then if CRC is OK */
+ if ((errors != -1) && (crc_ccitt(buf, rx_pkt.pl_len + 1U) == ((buf[rx_pkt.pl_len + 1U] << 8U) | buf[rx_pkt.pl_len + 2U])) )
+ {
+ /* Copy remaining fields and pass on */
+ rx_pkt.errors = errors;
+ rx_pkt.ngham_flags = (buf[0] & NGH_FLAGS_bm) >> NGH_FLAGS_bp;
+ (void)memcpy(rx_pkt.pl, &buf[1], rx_pkt.pl_len);
+ err = 0;
+ }
+ }
+ break;
+ default:
+ err = -1;
+
+ break;
+ }
+
+ return err;
+}
+
+static int ngham_init_arrays(void)
+{
+ int err = 0;
+ uint16_t j = 0U;
+
+ for(j = 0U; j < 3U; j++)
+ {
+ if (rsc_init(8, 0x187, 112, 11, 16, (NGH_PL_PAR_SIZE[6] - NGH_PL_PAR_SIZE[j]), &rs[j]) != 0)
+ {
+ err = -1;
+ }
+ }
+
+ for(; j < NGH_SIZES; j++)
+ {
+ if (rsc_init(8, 0x187, 112, 11, 32, (NGH_PL_PAR_SIZE[6] - NGH_PL_PAR_SIZE[j]), &rs[j]) != 0)
+ {
+ err = -1;
+ }
+ }
+
+ return err;
+}
+
+static uint8_t ngham_tag_check(uint32_t x, uint32_t y)
+{
+ uint8_t j = 0U;
+ uint8_t distance = 0U;
+ uint32_t diff = x ^ y;
+ uint8_t res = 0;
+
+ if (diff != 0U)
+ {
+ for(j = 0U; j < 24U; j++)
+ {
+ if ((diff & 0x01U) != 0U)
+ {
+ distance++;
+ if (distance > NGH_SIZE_TAG_MAX_ERROR)
+ {
+ res = 0;
+ break;
+ }
+ }
+
+ diff >>= 1;
+ }
+ }
+ else
+ {
+ res = 1;
+ }
+
+ return res;
+}
+
+/**< \} End of ngham group */
diff --git a/firmware/app/libs/ngham-1.0/src/ngham_extension.c b/firmware/app/libs/ngham-1.0/src/ngham_extension.c
new file mode 100644
index 00000000..7e97c3de
--- /dev/null
+++ b/firmware/app/libs/ngham-1.0/src/ngham_extension.c
@@ -0,0 +1,10 @@
+//**************************************************************//
+// NGHam protocol - Jon Petter Skagmo, LA3JPA, 2014. //
+// Licensed under LGPL. //
+//**************************************************************//
+
+#include "ngham/ngham_extension.h"
+
+#include "ngham/ngham_packets.h"
+#include "stdint.h"
+#include
diff --git a/firmware/app/libs/ngham-0.1/src/ngham_packets.c b/firmware/app/libs/ngham-1.0/src/ngham_packets.c
similarity index 89%
rename from firmware/app/libs/ngham-0.1/src/ngham_packets.c
rename to firmware/app/libs/ngham-1.0/src/ngham_packets.c
index ed853712..83e246a1 100644
--- a/firmware/app/libs/ngham-0.1/src/ngham_packets.c
+++ b/firmware/app/libs/ngham-1.0/src/ngham_packets.c
@@ -1,4 +1,4 @@
-#include "ngham_packets.h"
+#include "ngham/ngham_packets.h"
void rx_pkt_init(rx_pkt_t *p){
p->pl_len = 0;
diff --git a/firmware/app/libs/ngham-1.0/src/ngham_spp.c b/firmware/app/libs/ngham-1.0/src/ngham_spp.c
new file mode 100644
index 00000000..3c4b4453
--- /dev/null
+++ b/firmware/app/libs/ngham-1.0/src/ngham_spp.c
@@ -0,0 +1,142 @@
+// //**************************************************************//
+// // NGHam protocol - Jon Petter Skagmo, LA3JPA, 2014. //
+// // Licensed under LGPL. //
+// // This is made somewhat platform specific for the Owl VHF //
+// // with serial port contexts, and is meant as an guidance. //
+// //**************************************************************//
+
+// #include "ngham/ngham_spp.h"
+// #include "ngham/crc_ccitt.h"
+// #include // For memcpy
+
+// // Definition of port context port_ctx_t and port_* functions,
+// // as well as packer_call which sends data to transmit chain
+// //#include "ngham_paths.h"
+// #include PATH_NGHAM_PLATFORM_SPP
+
+// // Packet start byte definition
+// #define SPP_START 0x24
+
+// // States
+// #define SPP_STATE_START 0x00
+// #define SPP_STATE_HEADER 0x01
+// #define SPP_STATE_PAYLOAD 0x02
+
+// void ngham_parse_byte(port_ctx_t* ctx, uint8_t c){
+// switch(ctx->state){
+// case SPP_STATE_START:
+// if (c == SPP_START){
+// ctx->state = SPP_STATE_HEADER; // Start found; go to next state
+// ctx->d_ip = 1; // Starts at next first as SPP_START is already received
+// }
+// break;
+
+// case SPP_STATE_HEADER:
+// // Fill ctx->d with header - no check for size, as buffer is much larger than header (5B)
+// ctx->d[ctx->d_ip++] = c;
+
+// if (ctx->d_ip >= sizeof(ngh_spphdr_t)){
+// // Target length in d_op
+// ctx->d_op = sizeof(ngh_spphdr_t) + ((ngh_spphdr_t*)ctx->d)->pl_len;
+// ctx->state = SPP_STATE_PAYLOAD;
+// }
+// break;
+
+// case SPP_STATE_PAYLOAD:
+// // Fill ctx->d with payload
+// if (ctx->d_ip < PORT_BUF_SIZE) ctx->d[ctx->d_ip++] = c;
+
+// // If received length has met target length (set in STATE_HEADER)
+// if (ctx->d_ip >= ctx->d_op){
+// ngh_spphdr_t* hdr = (ngh_spphdr_t*)ctx->d;
+
+// if (crc_ccitt(ctx->d+3, ctx->d_ip-3) == hdr->crc){
+// switch(hdr->pl_type){
+
+// // Data to be sent
+// case NGHAM_SPP_TYPE_TX:
+// {
+// tx_pkt_t p;
+// tx_pkt_init(&p);
+
+// // Set flags, length (excluding flag-byte) and copy data
+// p.ngham_flags = ctx->d[sizeof(ngh_spphdr_t)];
+// p.pl_len = hdr->pl_len-1;
+// memcpy(p.pl, ctx->d+sizeof(ngh_spphdr_t)+1, p.pl_len);
+
+// // Packer call define - this is where the TX-packets are sent
+// packer_call(&p);
+
+// // TODO: Generate response!
+// }
+// break;
+
+// // Command
+// case NGHAM_SPP_TYPE_CMD:
+// {
+// uint8_t rep[REPLY_SIZE]; // CMD can be longer than SPP_PL_MAX
+// uint16_t rep_len = 0;
+// cmd(ctx->d+sizeof(ngh_spphdr_t), hdr->pl_len, rep, &rep_len, REPLY_SIZE); // Run command
+// ngham_print_cmd(ctx, rep, rep_len); // Send reply
+// }
+// break;
+// }
+// }
+
+// ctx->state = SPP_STATE_START;
+// }
+// break;
+// }
+// }
+
+// void ngham_spp_fill_header(ngh_spphdr_t* hdr, uint8_t type, uint8_t* d, uint16_t d_len){
+// uint16_t j, crc;
+
+// hdr->start = SPP_START;
+// hdr->pl_type = type;
+// hdr->pl_len = d_len;
+
+// crc = crc_ccitt_byte(hdr->pl_type, 0xffff);
+// crc = crc_ccitt_byte(hdr->pl_len, crc);
+// for (j=0; jcrc = crc;
+// }
+
+// void ngham_print_cmd(port_ctx_t* ctx, uint8_t* d, uint16_t d_len){
+// ngh_spphdr_t hdr;
+// uint16_t shortened_len, offset = 0;
+
+// // Split into multiple packets if necessary
+// while (d_len){
+// if (d_len > SPP_PL_MAX) shortened_len = SPP_PL_MAX;
+// else shortened_len = d_len;
+
+// ngham_spp_fill_header(&hdr, NGHAM_SPP_TYPE_CMD, d+offset, shortened_len);
+
+// // Copy remaining and send to port
+// port_output(ctx, (uint8_t*)&hdr, sizeof(ngh_spphdr_t));
+// port_output(ctx, d+offset, hdr.pl_len);
+
+// d_len -= shortened_len;
+// offset += shortened_len;
+// }
+// }
+
+// // Output buffer should be prefilled with
+// void ngham_print_rx_pkt(rx_pkt_t* p){
+// ngh_spphdr_t hdr;
+
+// ngham_spp_fill_header(&hdr, NGHAM_SPP_TYPE_RX, (uint8_t*)p, p->pl_len+8);
+// port_unpacker_output(PACKER_NGHAM, (uint8_t*)&hdr, sizeof(ngh_spphdr_t));
+// port_unpacker_output(PACKER_NGHAM, (uint8_t*)p, hdr.pl_len);
+// }
+
+// void ngham_pack_tx_pkt_local(tx_pkt_t* p){
+// ngh_spphdr_t hdr;
+
+// ngham_spp_fill_header(&hdr, NGHAM_SPP_TYPE_LOCAL, (uint8_t*)&(p->ngham_flags), p->pl_len+1);
+// port_unpacker_output(PACKER_NGHAM, (uint8_t*)&hdr, sizeof(ngh_spphdr_t));
+// port_unpacker_output(PACKER_NGHAM, (uint8_t*)&(p->ngham_flags), hdr.pl_len);
+// }
diff --git a/firmware/app/libs/ngham-1.0/tests/CMakeLists.txt b/firmware/app/libs/ngham-1.0/tests/CMakeLists.txt
new file mode 100644
index 00000000..14200ae3
--- /dev/null
+++ b/firmware/app/libs/ngham-1.0/tests/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 3.0)
+
+project(ngham_test C)
+
+include_directories(${CMAKE_SOURCE_DIR}/../include)
+include_directories(${CMAKE_SOURCE_DIR}/../rsclib/include)
+
+add_subdirectory(${CMAKE_SOURCE_DIR}/.. ${CMAKE_BINARY_DIR}/../build_ngham)
+
+add_executable(ngham_test ${CMAKE_SOURCE_DIR}/test.c)
+
+target_link_libraries(ngham_test cmocka ngham rsc)
\ No newline at end of file
diff --git a/firmware/app/libs/ngham-0.1/tests/README.md b/firmware/app/libs/ngham-1.0/tests/README.md
similarity index 67%
rename from firmware/app/libs/ngham-0.1/tests/README.md
rename to firmware/app/libs/ngham-1.0/tests/README.md
index e0a04157..43ac706e 100644
--- a/firmware/app/libs/ngham-0.1/tests/README.md
+++ b/firmware/app/libs/ngham-1.0/tests/README.md
@@ -5,10 +5,11 @@
* CMake
## Compiling and building
-
```
-cmake .
-make
+mkdir build_tests
+cd build_tests
+cmake ../
+cmake --build .
```
## Executing the test
diff --git a/firmware/app/libs/ngham-0.1/tests/test.c b/firmware/app/libs/ngham-1.0/tests/test.c
similarity index 56%
rename from firmware/app/libs/ngham-0.1/tests/test.c
rename to firmware/app/libs/ngham-1.0/tests/test.c
index 007f1092..36df9796 100644
--- a/firmware/app/libs/ngham-0.1/tests/test.c
+++ b/firmware/app/libs/ngham-1.0/tests/test.c
@@ -24,10 +24,11 @@
* \brief NGHam library unit test.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
*
- * \version 0.1.0
+ * \version 1.0.0
*
- * \date 2023/03/12
+ * \date 2024/06/03
*
* \defgroup test Test
* \ingroup ngham
@@ -37,12 +38,20 @@
#include
#include
#include
+#include
+#include
+#include
+#include
#include
#include
+#include
#include
+#include
#include
+uint16_t random_value(uint16_t min, uint16_t max);
+
static void ngham_init_test(void **state)
{
assert_return_code(ngham_init(), 0);
@@ -68,6 +77,67 @@ static void ngham_encode_test(void **state)
static void ngham_decode_test(void **state)
{
+ uint16_t i = 0U;
+ uint8_t expected_data[300];
+ uint8_t data[300];
+ uint16_t expected_data_len;
+ uint8_t rand_number_of_errors;
+ bool rand_error_pos_arr[255];
+ uint16_t rand_error_position;
+ uint8_t rand_error_value;
+
+ expected_data_len = random_value(1, 220);
+
+ for (i = 0U; i.
- *
- */
-
-/**
- * \brief Reed-Solomon C library implementation.
- *
- * \author Gabriel Mariano Marcelino
- *
- * \version 0.1.0
- *
- * \date 2022/03/06
- *
- * \addtogroup rsclib
- * \{
- */
-
-#include
-
-#include
-
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-/**
- * \brief Computes the modulo of a given number.
- *
- * \param[in] rs is the Reed-Solomon scheme used to compute the modulo.
- *
- * \param[in] x is the integer to compute the modulo.
- *
- * \return The computed modulo value of the given number.
- */
-int modnn(reed_solomon_t *rs, int x);
-
-int rsc_init(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad, reed_solomon_t *rs)
-{
- int err = 0;
-
- int i, j, sr, root, iprim;
-
- /* Check parameter ranges */
- if ((symsize >= 0) && (symsize <= (8 * sizeof(uint8_t))))
- {
- if ((fcr >= 0) && (fcr < (1 << symsize)))
- {
- if ((prim > 0) && (prim < (1 << symsize)))
- {
- if ((nroots >= 0) && (nroots < (1 << symsize)))
- {
- if ((pad >= 0) && (pad < ((1 << symsize) - 1 - nroots)))
- {
- rs->mm = symsize;
- rs->nn = (1 << symsize) - 1;
- rs->pad = pad;
-
- /* Generate Galois field lookup tables */
- rs->index_of[0] = rs->nn; /* log(zero) = -inf */
- rs->alpha_to[rs->nn] = 0; /* alpha**-inf = 0 */
- sr = 1;
- for(i = 0; i < rs->nn; i++)
- {
- rs->index_of[sr] = i;
- rs->alpha_to[i] = sr;
- sr <<= 1;
- if (sr & (1 << symsize))
- {
- sr ^= gfpoly;
- }
- sr &= rs->nn;
- }
- if (sr == 1)
- {
- rs->fcr = fcr;
- rs->prim = prim;
- rs->nroots = nroots;
-
- /* Find prim-th root of 1, used in decoding */
- for(iprim = 1; (iprim % prim) != 0; iprim += rs->nn)
- {
- }
- rs->iprim = iprim / prim;
-
- rs->genpoly[0] = 1;
- for(i = 0, root = fcr * prim; i < nroots; i++, root += prim)
- {
- rs->genpoly[i + 1] = 1;
-
- /* Multiply rs->genpoly[] by @**(root + x) */
- for(j = i; j > 0; j--)
- {
- if (rs->genpoly[j] != 0)
- {
- rs->genpoly[j] = rs->genpoly[j - 1] ^ rs->alpha_to[modnn(rs, rs->index_of[rs->genpoly[j]] + root)];
- }
- else
- {
- rs->genpoly[j] = rs->genpoly[j - 1];
- }
- }
- /* rs->genpoly[0] can never be zero */
- rs->genpoly[0] = rs->alpha_to[modnn(rs, rs->index_of[rs->genpoly[0]] + root)];
- }
- /* convert rs->genpoly[] to index form for quicker encoding */
- for(i = 0; i <= nroots; i++)
- {
- rs->genpoly[i] = rs->index_of[rs->genpoly[i]];
- }
-
- err = 0;
- }
- else
- {
- /* field generator polynomial is not primitive! */
- memset(rs, 0, sizeof(reed_solomon_t));
-
- err = -1;
- }
- }
- else
- {
- err = 0; /* Too much padding */
- }
- }
- else
- {
- err = -1; /* Can't have more roots than symbol values! */
- }
- }
- else
- {
- err = -1;
- }
- }
- else
- {
- err = -1;
- }
- }
- else
- {
- err = -1;
- }
-
- return err;
-}
-
-void rsc_encode(reed_solomon_t *rs, uint8_t *data, uint8_t *parity, uint8_t *parity_len)
-{
- int i = 0;
- int j = 0;
- int feedback = 0;
-
- memset(parity, 0, rs->nroots);
-
- for(i = 0; i < (rs->nn - rs->nroots - rs->pad); i++)
- {
- feedback = rs->index_of[data[i] ^ parity[0]];
- if (feedback != rs->nn) /* feedback term is non-zero */
- {
- for(j = 0; j < rs->nroots; j++)
- {
- parity[j] ^= rs->alpha_to[modnn(rs, feedback + rs->genpoly[rs->nroots - j])];
- }
- }
- /* Shift */
- memmove(&parity[0], &parity[1], rs->nroots - 1);
- if (feedback != rs->nn)
- {
- parity[rs->nroots - 1] = rs->alpha_to[modnn(rs, feedback + rs->genpoly[0])];
- }
- else
- {
- parity[rs->nroots - 1] = 0U;
- }
- }
-
- *parity_len = rs->nroots;
-}
-
-int rsc_decode(reed_solomon_t *rs, uint8_t *pkt, uint8_t *data, uint8_t *err_pos, uint8_t *num_err)
-{
- int err = -1;
-
-// int deg_lambda = 0;
-// int el = 0;
-// int deg_omega = 0;
-// int u = 0;
-// int q = 0;
-// int tmp = 0;
-// int num1 = 0;
-// int num2 = 0;
-// int den = 0;
-// int discr_r = 0;
-// uint8_t lambda[32 + 1] = {0U};
-// uint8_t s[32] = {0U};
-// uint8_t b[32 + 1] = {0U};
-// uint8_t t[32 + 1] = {0U};
-// uint8_t omega[32 + 1] = {0U};
-// uint8_t root[32] = {0U};
-// uint8_t reg[32 + 1] = {0U};
-// uint8_t loc[32] = {0U};
-// int syn_error = 0;
-// int count = 0;
-//
-// int i = 0;
-// int j = 0;
-//
-// /* Form the syndromes; i.e., evaluate data(x) at roots of g(x) */
-// memset(s, data[0], rs->nroots);
-//
-// for(j = 1; j < (rs->nn - rs->pad); j++)
-// {
-// for(i = 0; i < rs->nroots; i++)
-// {
-// if (s[i] == 0)
-// {
-// s[i] = data[j];
-// }
-// else
-// {
-// s[i] = data[j] ^ rs->alpha_to[modnn(rs, rs->index_of[s[i]] + (rs->fcr + i) * rs->prim)];
-// }
-// }
-// }
-//
-// /* Convert syndromes to index form, checking for nonzero condition */
-// syn_error = 0;
-// for(i = 0; i < rs->nroots; i++)
-// {
-// syn_error |= s[i];
-// s[i] = rs->index_of[s[i]];
-// }
-//
-// if (not syn_error)
-// {
-// /* if syndrome is zero, data[] is a codeword and there are no errors to correct. So return data[] unmodified */
-// count = 0;
-// }
-// else
-// {
-// lambda[0] = 1;
-//
-// if (no_eras > 0)
-// {
-// /* Init lambda to be the erasure locator polynomial */
-// lambda[1] = rs->alpha_to[modnn(rs, rs->prim * (rs->nn - 1 - eras_pos[0]))]
-// for(i = 1; i < no_eras; i++)
-// {
-// u = modnn(rs, rs->prim * (rs->nn - 1 - eras_pos[i]));
-// for(j = i + 1; i > 0; i--)
-// {
-// tmp = rs->index_of[lambda[j - 1]];
-// if (tmp != rs->nn)
-// {
-// lambda[j] ^= rs->alpha_to[modnn(rs, u + tmp)];
-// }
-// }
-// }
-// }
-//
-// for(i = 0; i < (rs->nroots + 1); i++)
-// {
-// b[i] = rs->index_of[lambda[i]];
-// }
-//
-// /* Begin Berlekamp-Massey algorithm to determine error+erasure locator polynomial */
-// r = no_eras + 1;
-// el = no_eras;
-// while(r <= rs->nroots) /* r is the step number */
-// {
-// /* Compute discrepancy at the r-th step in poly-form */
-// discr_r = 0;
-// for(i = 0; i < r; i++)
-// {
-// if ((lambda[i] != 0) && (s[r - i - 1] != rs->nn))
-// {
-// discr_r ^= rs->alpha_to[modnn(rs, rs->index_of[lambda[i]] + s[r - i - 1])];
-// }
-// }
-// discr_r = rs->index_of[discr_r]; /* Index form */
-// if (discr_r == rs->nn)
-// {
-// /* 2 lines below: B(x) <-- x*B(x) */
-// b.insert(0, rs->nn)
-// }
-// else
-// {
-// /* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
-// t[0] = lambda[0];
-// for(i = 0; i < rs->nroots; i++)
-// {
-// if (b[i] != rs->nn)
-// {
-// t[i + 1] = lambda[i + 1] ^ rs->alpha_to[modnn(rs, discr_r + b[i])];
-// }
-// else
-// {
-// t[i + 1] = lambda[i + 1];
-// }
-// }
-// if (2 * el <= r + no_eras - 1):
-// {
-// el = r + no_eras - el;
-// /* 2 lines below: B(x) <-- inv(discr_r) * lambda(x) */
-// for(i = 0; i < (rs->nroots + 1); i++)
-// {
-// if (lambda[i] == 0)
-// {
-// b[i] = rs->nn;
-// }
-// else
-// {
-// b[i] = modnn(rs, rs->index_of[lambda[i]] - discr_r + rs->nn);
-// }
-// }
-// }
-// else
-// {
-// /* 2 lines below: B(x) <-- x*B(x) */
-// b.insert(0, rs->nn)
-// }
-// lambda = t[:rs->nroots + 1]
-// }
-// r++;
-// }
-//
-// /* Convert lambda to index form and compute deg(lambda(x)) */
-// deg_lambda = 0;
-// for(i = 0; i < (rs->nroots + 1); i++)
-// {
-// lambda[i] = rs->index_of[lambda[i]];
-// if (lambda[i] != rs->nn)
-// {
-// deg_lambda = i;
-// }
-// }
-// /* Find roots of the error+erasure locator polynomial by Chien search */
-// reg[1:] = lambda[1:rs->nroots + 1]
-// count = 0; /* Number of roots of _lambda(x) */
-// k = rs->iprim - 1;
-// for(i = 1; i < (rs->nn + 1); i++)
-// {
-// q = 1; /* lambda[0] is always 0 */
-// for(j = deg_lambda; j > 0; j--)
-// {
-// if (reg[j] != rs->nn)
-// {
-// reg[j] = modnn(rs, reg[j] + j);
-// q ^= rs->alpha_to[reg[j]];
-// }
-// }
-// if (q != 0)
-// {
-// k = modnn(rs, k + rs->iprim);
-// continue; /* Not a root */
-// }
-// /* store root (index-form) and error location number */
-// root[count] = i;
-// loc[count] = k;
-// /* If we've already found max possible roots, abort the search to save time */
-// count++;
-// if (count == deg_lambda)
-// {
-// break;
-// }
-// k = modnn(rs, k + rs->iprim)
-// }
-// if (deg_lambda != count)
-// {
-// /* deg(lambda) unequal to number of roots => uncorrectable error detected */
-// count = -1
-// }
-// else
-// {
-// /* Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo x**rs.nroots). in index form. Also find deg(omega) */
-// deg_omega = deg_lambda - 1;
-// for(i = 0; i < (deg_omega + 1); i++)
-// {
-// tmp = 0;
-// for(j = i; j > -1; j--)
-// {
-// if ((s[i - j] != rs->nn) && (lambda[j] != rs->nn))
-// {
-// tmp ^= rs->alpha_to[modnn(rs, s[i - j] + lambda[j])];
-// }
-// }
-// omega[i] = rs->index_of[tmp];
-// }
-//
-// /* Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = inv(X(l))**(rs.fcr-1) and den = lambda_pr(inv(X(l))) all in poly-form */
-// for(j = (count - 1); j > -1; j--)
-// {
-// num1 = 0;
-// for(i = deg_omega; j > -1; j--)
-// {
-// if (omega[i] != rs->nn)
-// {
-// num1 ^= rs->alpha_to[modnn(rs, omega[i] + i * root[j])];
-// }
-// }
-// num2 = rs->alpha_to[modnn(rs, root[j] * (rs->fcr - 1) + rs->nn)];
-// den = 0;
-//
-// /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
-// for i in range(min(deg_lambda, rs->nroots - 1) & ~1, -1, -2):
-// {
-// if (lambda[i + 1] != rs->nn)
-// {
-// den ^= rs->alpha_to[modnn(lambda[i + 1] + i * root[j])];
-// }
-// }
-// /* Apply error to data */
-// if (num1 != 0 && loc[j] >= rs->pad):
-// {
-// data[loc[j] - rs->pad] = data[loc[j] - rs->pad] ^ rs->alpha_to[modnn(rs, rs->index_of[num1] + rs->index_of[num2] + rs->nn - rs->index_of[den])];
-// }
-// }
-// }
-// }
-//
-// if (eras_pos != None)
-// {
-// for(i = 0; i < count; i++)
-// {
-// eras_pos[i] = loc[i];
-// }
-// }
-//
-// err = count;
-//
-// return data, retval, eras_pos
-// return err;
-}
-
-int modnn(reed_solomon_t *rs, int x)
-{
- while(x >= rs->nn)
- {
- x -= rs->nn;
- x = (x >> rs->mm) + (x & rs->nn);
- }
-
- return x;
-}
-
-/**< \} End of rsclib group */
diff --git a/firmware/app/structs/ttc_data.c b/firmware/app/structs/ttc_data.c
index 6003f30b..3dd0e47a 100644
--- a/firmware/app/structs/ttc_data.c
+++ b/firmware/app/structs/ttc_data.c
@@ -26,9 +26,9 @@
* \author Gabriel Mariano Marcelino
* \author Miguel Boing
*
- * \version 0.4.5
- *
- * \date 2021/04/14
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \addtogroup ttc_data
* \{
@@ -42,11 +42,11 @@ ttc_data_t ttc_data_buf;
void downlink_add_packet(uint8_t *packet, uint16_t packet_size)
{
- uint16_t i = 0;
+ uint16_t i = 0U;
ttc_data_buf.down_buf.packet_sizes[ttc_data_buf.down_buf.position_to_write] = packet_size;
- for(i = 0; i = 5)
+ if (++ttc_data_buf.down_buf.position_to_write >= 5U)
{
- ttc_data_buf.down_buf.position_to_write = 0;
+ ttc_data_buf.down_buf.position_to_write = 0U;
}
}
void downlink_pop_packet(uint8_t *packet, uint16_t *packet_size)
{
- uint16_t i = 0;
+ uint16_t i = 0U;
- *packet_size = ttc_data_buf.down_buf.packet_sizes[ttc_data_buf.down_buf.position_to_read];
-
- for(i = 0; i < ttc_data_buf.down_buf.packet_sizes[ttc_data_buf.down_buf.position_to_read]; i++)
+ if (ttc_data_buf.radio.tx_fifo_counter > 0U)
{
- packet[i] = ttc_data_buf.down_buf.packet_array[ttc_data_buf.down_buf.position_to_read][i];
- }
+ *packet_size = ttc_data_buf.down_buf.packet_sizes[ttc_data_buf.down_buf.position_to_read];
- ttc_data_buf.radio.tx_fifo_counter--;
+ for(i = 0U; i < ttc_data_buf.down_buf.packet_sizes[ttc_data_buf.down_buf.position_to_read]; i++)
+ {
+ packet[i] = ttc_data_buf.down_buf.packet_array[ttc_data_buf.down_buf.position_to_read][i];
+ }
- if (++ttc_data_buf.down_buf.position_to_read >= 5)
- {
- ttc_data_buf.down_buf.position_to_read = 0;
+ ttc_data_buf.radio.tx_fifo_counter--;
+
+ if (++ttc_data_buf.down_buf.position_to_read >= 5U)
+ {
+ ttc_data_buf.down_buf.position_to_read = 0U;
+ }
}
}
void uplink_add_packet(uint8_t *packet, uint16_t packet_size)
{
- uint16_t i = 0;
+ uint16_t i = 0U;
ttc_data_buf.up_buf.packet_sizes[ttc_data_buf.up_buf.position_to_write] = packet_size;
@@ -103,26 +106,25 @@ void uplink_pop_packet(uint8_t *packet, uint16_t *packet_size)
{
uint16_t i = 0;
- *packet_size = ttc_data_buf.up_buf.packet_sizes[ttc_data_buf.up_buf.position_to_read];
-
- for(i = 0; i < ttc_data_buf.up_buf.packet_sizes[ttc_data_buf.up_buf.position_to_read]; i++)
+ if (ttc_data_buf.radio.rx_fifo_counter > 0U)
{
- packet[i] = ttc_data_buf.up_buf.packet_array[ttc_data_buf.up_buf.position_to_read][i];
- ttc_data_buf.up_buf.packet_array[ttc_data_buf.up_buf.position_to_read][i] = 0xFF; /* Remove packet after a read */
- }
+ *packet_size = ttc_data_buf.up_buf.packet_sizes[ttc_data_buf.up_buf.position_to_read];
- ttc_data_buf.up_buf.packet_sizes[ttc_data_buf.up_buf.position_to_read] = 0xFF; /* 0xFF means that there is no package in this position */
+ for(i = 0; i < ttc_data_buf.up_buf.packet_sizes[ttc_data_buf.up_buf.position_to_read]; i++)
+ {
+ packet[i] = ttc_data_buf.up_buf.packet_array[ttc_data_buf.up_buf.position_to_read][i];
+ ttc_data_buf.up_buf.packet_array[ttc_data_buf.up_buf.position_to_read][i] = 0xFF; /* Remove packet after a read */
+ }
- ttc_data_buf.radio.rx_fifo_counter--;
+ ttc_data_buf.up_buf.packet_sizes[ttc_data_buf.up_buf.position_to_read] = 0x00; /* 0x00 means that there is no package in this position */
- if (++ttc_data_buf.up_buf.position_to_read >= 5)
- {
- ttc_data_buf.up_buf.position_to_read = 0;
- }
-
- /* Update rx packet bytes */
- ttc_data_buf.radio.last_rx_packet_bytes = &(ttc_data_buf.up_buf.packet_sizes[ttc_data_buf.up_buf.position_to_read]);
+ ttc_data_buf.radio.rx_fifo_counter--;
+ if (++ttc_data_buf.up_buf.position_to_read >= 5)
+ {
+ ttc_data_buf.up_buf.position_to_read = 0;
+ }
+ }
}
/** \} End of ttc_data group */
diff --git a/firmware/app/tasks/beacon.c b/firmware/app/tasks/beacon.c
deleted file mode 100644
index 069a665f..00000000
--- a/firmware/app/tasks/beacon.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * beacon.c
- *
- * Copyright The TTC 2.0 Contributors.
- *
- * This file is part of TTC 2.0.
- *
- * TTC 2.0 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * TTC 2.0 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with TTC 2.0. If not, see .
- *
- */
-
-/**
- * \brief Beacon task implementation.
- *
- * \author Gabriel Mariano Marcelino
- *
- * \version 0.4.4
- *
- * \date 2019/10/27
- *
- * \addtogroup beacon
- * \{
- */
-
-#include
-#include
-#include
-#include
-
-#include "beacon.h"
-#include "startup.h"
-
-xTaskHandle xTaskBeaconHandle;
-
-void vTaskBeacon(void)
-{
- /* Wait startup task to finish */
- xEventGroupWaitBits(task_startup_status, TASK_STARTUP_DONE, pdFALSE, pdTRUE, pdMS_TO_TICKS(TASK_BEACON_INIT_TIMEOUT_MS));
-
- /* Delay before the first cycle */
- vTaskDelay(pdMS_TO_TICKS(TASK_BEACON_INITIAL_DELAY_MS));
-
- uint8_t tx_pkt[30] = {0};
- uint16_t tx_pkt_len = UINT8_MAX;
-
- uint8_t ngham_pkt[60] = {0};
- uint16_t ngham_pkt_len = UINT16_MAX;
-
- while(1)
- {
- TickType_t last_cycle = xTaskGetTickCount();
-
- /* Beacon data */
- uint8_t data[30] = {0};
- uint16_t data_len = 1;
-
- fsat_pkt_pl_t beacon_pl;
-
- /* Packet ID */
- fsat_pkt_add_id(&beacon_pl, CONFIG_PKT_ID_BEACON);
-
- /* Source callsign */
- fsat_pkt_add_callsign(&beacon_pl, CONFIG_SATELLITE_CALLSIGN);
-
- /* Payload data */
- fsat_pkt_add_payload(&beacon_pl, data, data_len);
-
- fsat_pkt_encode(beacon_pl, tx_pkt, &tx_pkt_len);
-
- if (ngham_encode(tx_pkt, tx_pkt_len, 0U, ngham_pkt, &ngham_pkt_len) == 0)
- {
- radio_send(&ngham_pkt[8], ngham_pkt_len); /* 8 = Removing preamble and sync word */
- }
- else
- {
- sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_BEACON_NAME, "Error encoding a NGHam packet!");
- sys_log_new_line();
- }
-
- vTaskDelayUntil(&last_cycle, pdMS_TO_TICKS(TASK_BEACON_PERIOD_MS));
- }
-}
-
-/** \} End of beacon group */
diff --git a/firmware/app/tasks/beacon.h b/firmware/app/tasks/beacon.h
deleted file mode 100644
index 387cd9ab..00000000
--- a/firmware/app/tasks/beacon.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * beacon.h
- *
- * Copyright (C) 2021, SpaceLab.
- *
- * This file is part of TTC 2.0.
- *
- * TTC 2.0 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * TTC 2.0 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with TTC 2.0. If not, see .
- *
- */
-
-/**
- * \brief Beacon task definition.
- *
- * \author Gabriel Mariano Marcelino
- *
- * \version 0.1.10
- *
- * \date 2019/10/27
- *
- * \defgroup beacon Beacon
- * \ingroup tasks
- * \{
- */
-
-#ifndef BEACON_H_
-#define BEACON_H_
-
-#include
-#include
-
-#define TASK_BEACON_NAME "Beacon" /**< Task name. */
-#define TASK_BEACON_STACK_SIZE 2000 /**< Stack size in bytes. */
-#define TASK_BEACON_PRIORITY 5 /**< Task priority. */
-#define TASK_BEACON_PERIOD_MS 60000 /**< Task period in milliseconds. */
-#define TASK_BEACON_INITIAL_DELAY_MS 1000 /**< Delay, in milliseconds, before the first execution. */
-#define TASK_BEACON_INIT_TIMEOUT_MS 10000 /**< Wait time to initialize the task in milliseconds. */
-
-/**
- * \brief Beacon handle.
- */
-extern xTaskHandle xTaskBeaconHandle;
-
-/**
- * \brief Beacon task.
- *
- * \return None.
- */
-void vTaskBeacon(void);
-
-#endif /* BEACON_H_ */
-
-/** \} End of beacon group */
diff --git a/firmware/app/tasks/downlink_manager.c b/firmware/app/tasks/downlink_manager.c
index de389f8c..43902d6d 100644
--- a/firmware/app/tasks/downlink_manager.c
+++ b/firmware/app/tasks/downlink_manager.c
@@ -26,9 +26,9 @@
* \author Miguel Boing
* \author Gabriel Mariano Marcelino
*
- * \version 0.4.5
+ * \version 1.0.0
*
- * \date 2023/03/03
+ * \date 2024/09/09
*
* \addtogroup downlink_manager
* \{
@@ -37,6 +37,7 @@
#include
#include
#include
+#include
#include "downlink_manager.h"
#include "startup.h"
@@ -75,18 +76,31 @@ void vTaskDownlinkManager(void)
if ((ttc_data_buf.radio.tx_fifo_counter > 0) && (ttc_data_buf.radio.tx_enable == 1U))
{
- sys_log_print_event_from_module(SYS_LOG_INFO, TASK_DOWNLINK_MANAGER_NAME, "Sending packet...");
+ sys_log_print_event_from_module(SYS_LOG_INFO, TASK_DOWNLINK_MANAGER_NAME, "Sending packet:");
sys_log_new_line();
downlink_pop_packet(tx_pkt, &tx_pkt_len);
if (ngham_encode(tx_pkt, tx_pkt_len, 0U, ngham_pkt, &ngham_pkt_len) == 0)
{
- radio_send(&ngham_pkt[8], ngham_pkt_len); /* 8 = Removing preamble and sync word */
+ sys_log_print_event_from_module(SYS_LOG_INFO, TASK_DOWNLINK_MANAGER_NAME, "Encoding packet...");
+ sys_log_new_line();
+
+ if (radio_send(&ngham_pkt[8], ngham_pkt_len) == 0)
+ {
+ sys_log_print_event_from_module(SYS_LOG_INFO, TASK_DOWNLINK_MANAGER_NAME, "Packet successfully transmitted");
+ sys_log_new_line();/* 8 = Removing preamble and sync word */
+ }
+ else
+ {
+ sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DOWNLINK_MANAGER_NAME, "Failed to transmit the packet");
+ sys_log_new_line();
+
+ }
}
else
{
- sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DOWNLINK_MANAGER_NAME, "Error encoding a NGHam packet!");
+ sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_DOWNLINK_MANAGER_NAME, "Error encoding a NGHam packet");
sys_log_new_line();
}
}
diff --git a/firmware/app/tasks/eps_server.c b/firmware/app/tasks/eps_server.c
index 7aa4a716..36c3d305 100644
--- a/firmware/app/tasks/eps_server.c
+++ b/firmware/app/tasks/eps_server.c
@@ -25,9 +25,9 @@
*
* \author Miguel Boing
*
- * \version 0.4.3
+ * \version 1.0.0
*
- * \date 2023/03/03
+ * \date 2024/09/09
*
* \addtogroup eps_server
* \{
@@ -73,18 +73,6 @@ void vTaskEpsServer(void)
sys_log_print_msg(" bytes!");
sys_log_new_line();
- sys_log_print_str("Packet: ");
-
- uint16_t i = 0;
-
- for(i = 0; i < eps_request.data.data_packet.len; i++)
- {
- sys_log_print_hex(eps_request.data.data_packet.packet[i]);
- sys_log_print_str("|");
- }
-
- sys_log_new_line();
-
downlink_add_packet(eps_request.data.data_packet.packet, eps_request.data.data_packet.len);
break;
diff --git a/firmware/app/tasks/eps_server.h b/firmware/app/tasks/eps_server.h
index a9fbf253..a6d0c78c 100644
--- a/firmware/app/tasks/eps_server.h
+++ b/firmware/app/tasks/eps_server.h
@@ -25,9 +25,9 @@
*
* \author Miguel Boing
*
- * \version 0.3.5
+ * \version 1.0.0
*
- * \date 2023/03/03
+ * \date 2024/09/09
*
* \defgroup eps EPS
* \ingroup tasks
@@ -41,9 +41,9 @@
#include
#define TASK_EPS_SERVER_NAME "EPS Server" /**< Task name. */
-#define TASK_EPS_SERVER_STACK_SIZE 2000 /**< Stack size in bytes. */
-#define TASK_EPS_SERVER_PRIORITY 4 /**< Task priority. */
-#define TASK_EPS_SERVER_PERIOD_MS 250 /**< Task period in milliseconds. */
+#define TASK_EPS_SERVER_STACK_SIZE 1000 /**< Stack size in bytes. */
+#define TASK_EPS_SERVER_PRIORITY 3 /**< Task priority. */
+#define TASK_EPS_SERVER_PERIOD_MS 750 /**< Task period in milliseconds. */
#define TASK_EPS_SERVER_INITIAL_DELAY_MS 1000 /**< Delay, in milliseconds, before the first execution. */
#define TASK_EPS_SERVER_INIT_TIMEOUT_MS 10000 /**< Wait time to initialize the task in milliseconds. */
diff --git a/firmware/app/tasks/obdh_server.c b/firmware/app/tasks/obdh_server.c
index 703b661e..aba78656 100644
--- a/firmware/app/tasks/obdh_server.c
+++ b/firmware/app/tasks/obdh_server.c
@@ -25,9 +25,9 @@
*
* \author Miguel Boing
*
- * \version 0.4.5
+ * \version 1.0.0
*
- * \date 2023/03/03
+ * \date 2024/09/09
*
* \addtogroup obdh_server
* \{
@@ -62,85 +62,101 @@ void vTaskObdhServer(void)
obdh_response_t obdh_response = {0};
obdh_request.command = 0x00U; /* No command */
- uint8_t buffer1[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- uint8_t buffer2[7] = {0x22, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t buffer3[10] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11};
-
- uplink_add_packet(buffer2, 6);
- uplink_add_packet(buffer3, 10);
-
while(1)
{
TickType_t last_cycle = xTaskGetTickCount();
/* Receiving data from obdh */
- obdh_read_request(&obdh_request);
-
- if (obdh_request.command != 0xFF)
+ if (obdh_read_request(&obdh_request) != -1)
{
- taskENTER_CRITICAL();
-
- switch(obdh_request.command)
+ if (obdh_request.command != 0xFF)
{
- case CMDPR_CMD_READ_PARAM:
- obdh_response.command = obdh_request.command;
- obdh_response.parameter = obdh_request.parameter;
- obdh_write_response_param(&ttc_data_buf, &obdh_response);
+ taskENTER_CRITICAL();
+
+ switch(obdh_request.command)
+ {
+ case CMDPR_CMD_READ_PARAM:
+ obdh_response.command = obdh_request.command;
+ obdh_response.parameter = obdh_request.parameter;
+ obdh_write_response_param(&ttc_data_buf, &obdh_response);
+
+ obdh_send_response(&obdh_response);
+
+ break;
+ case CMDPR_CMD_WRITE_PARAM:
+ obdh_write_read_bytes(7);
+
+ switch(obdh_request.parameter)
+ {
+ case CMDPR_PARAM_TX_ENABLE:
+ sys_log_print_event_from_module(SYS_LOG_INFO, TASK_OBDH_SERVER_NAME, "TX is now ");
- obdh_send_response(&obdh_response);
+ switch(obdh_request.data.param_8)
+ {
+ case 0x00:
+ sys_log_print_msg("Turned off.");
+ ttc_data_buf.radio.tx_enable = obdh_request.data.param_8;
- break;
- case CMDPR_CMD_WRITE_PARAM:
- obdh_write_read_bytes(6);
+ break;
+ case 0x01:
+ sys_log_print_msg("Turned on.");
+ ttc_data_buf.radio.tx_enable = obdh_request.data.param_8;
- sys_log_print_event_from_module(SYS_LOG_INFO, TASK_OBDH_SERVER_NAME, "TX is now ");
+ break;
+ default:
- switch(obdh_request.data.param_8)
- {
- case 0x00:
- sys_log_print_msg("Turned on.");
- ttc_data_buf.radio.tx_enable = obdh_request.data.param_8;
+ sys_log_print_msg("Invalid mode: ");
+ sys_log_print_uint(obdh_request.data.param_8);
+
+ break;
+ }
+
+ sys_log_new_line();
break;
- case 0x01:
- sys_log_print_msg("Turned off.");
- ttc_data_buf.radio.tx_enable = obdh_request.data.param_8;
+ case CMDPR_PARAM_RESET_DEVICE:
+ if (obdh_request.data.param_8 == 0x01)
+ {
+ sys_log_print_event_from_module(SYS_LOG_INFO, TASK_OBDH_SERVER_NAME, "Received command to reset system...");
+ system_reset();
+ }
break;
+
default:
- sys_log_print_msg("Invalid mode: ");
- sys_log_print_uint(obdh_request.data.param_8);
+ sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_OBDH_SERVER_NAME, "Invalid write parameter.");
break;
- }
- sys_log_new_line();
+ }
+ break;
+ case CMDPR_CMD_TRANSMIT_PACKET:
+ obdh_write_read_bytes(7);
- break;
- case CMDPR_CMD_TRANSMIT_PACKET:
- obdh_write_read_bytes(6);
+ downlink_add_packet(obdh_request.data.data_packet.packet, obdh_request.data.data_packet.len);
- downlink_add_packet(obdh_request.data.data_packet.packet, (obdh_request.data.data_packet.len)+3);
+ break;
+ case CMDPR_CMD_READ_FIRST_PACKET:
+ obdh_response.command = obdh_request.command;
- break;
- case CMDPR_CMD_READ_FIRST_PACKET:
- obdh_response.command = obdh_request.command;
+ uplink_pop_packet(obdh_response.data.data_packet.packet, &(obdh_response.data.data_packet.len));
- uplink_pop_packet(obdh_response.data.data_packet.packet, &(obdh_response.data.data_packet.len));
+ obdh_send_response(&obdh_response);
- obdh_send_response(&obdh_response);
+ obdh_write_read_bytes(7U);
- break;
- case 0x00:
- /* Read mode */
- obdh_write_read_bytes(6);
- break;
- default:
- break;
- }
+ break;
+ case 0x00:
+ /* Read mode */
+ obdh_write_read_bytes(7U);
- taskEXIT_CRITICAL();
- }
+ break;
+ default:
+ break;
+ }
+ taskEXIT_CRITICAL();
+ }
+ }
vTaskDelayUntil(&last_cycle, pdMS_TO_TICKS(TASK_OBDH_SERVER_PERIOD_MS));
}
}
diff --git a/firmware/app/tasks/obdh_server.h b/firmware/app/tasks/obdh_server.h
index 8659e6ea..f157c7d2 100644
--- a/firmware/app/tasks/obdh_server.h
+++ b/firmware/app/tasks/obdh_server.h
@@ -25,9 +25,9 @@
*
* \author Miguel Boing
*
- * \version 0.4.5
+ * \version 1.0.0
*
- * \date 2023/03/03
+ * \date 2024/09/09
*
* \defgroup obdh OBDH
* \ingroup tasks
@@ -41,7 +41,7 @@
#include
#define TASK_OBDH_SERVER_NAME "OBDH Server" /**< Task name. */
-#define TASK_OBDH_SERVER_STACK_SIZE 4000 /**< Stack size in bytes. */
+#define TASK_OBDH_SERVER_STACK_SIZE 2000 /**< Stack size in bytes. */
#define TASK_OBDH_SERVER_PRIORITY 5 /**< Task priority. */
#define TASK_OBDH_SERVER_PERIOD_MS 100 /**< Task period in milliseconds. */
#define TASK_OBDH_SERVER_INITIAL_DELAY_MS 200 /**< Delay, in milliseconds, before the first execution. */
diff --git a/firmware/app/tasks/read_sensors.c b/firmware/app/tasks/read_sensors.c
index 6645d6ad..591ebe69 100644
--- a/firmware/app/tasks/read_sensors.c
+++ b/firmware/app/tasks/read_sensors.c
@@ -25,15 +25,17 @@
*
* \author Gabriel Mariano Marcelino
* \author Miguel Boing
- *
- * \version 0.2.4
- *
- * \date 2020/07/12
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \addtogroup read_sensors
* \{
*/
+#include
+
#include
#include
#include
@@ -58,9 +60,14 @@ void vTaskReadSensors(void)
power_sensor_data_t pwr_sensor_buf;
/* uC temperature */
- if (temp_sensor_read_raw(&buf) == 0)
+ if (temp_sensor_read_k(&buf) == 0)
{
ttc_data_buf.temperature = buf;
+ sys_log_print_event_from_module(SYS_LOG_INFO, TASK_READ_SENSORS_NAME, "Current uC temperature: ");
+ sys_log_print_uint((uint32_t)buf);
+ sys_log_print_msg(" K");
+ sys_log_new_line();
+
}
/* uC current, voltage and power*/
diff --git a/firmware/app/tasks/startup.c b/firmware/app/tasks/startup.c
index c68e1993..24864e2b 100644
--- a/firmware/app/tasks/startup.c
+++ b/firmware/app/tasks/startup.c
@@ -24,10 +24,11 @@
* \brief Startup task implementation.
*
* \author Gabriel Mariano Marcelino
- *
- * \version 0.4.5
- *
- * \date 2019/12/04
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \addtogroup startup
* \{
@@ -64,6 +65,11 @@ void vTaskStartup(void)
/* Logger device initialization */
sys_log_init();
+ /* Print the TTC radio module */
+ sys_log_print_event_from_module(SYS_LOG_INFO, TASK_STARTUP_NAME, "Booting TTC Module ");
+ sys_log_print_uint((uint32_t)RADIO_MODULE);
+ sys_log_new_line();
+
/* Print the FreeRTOS version */
sys_log_print_event_from_module(SYS_LOG_INFO, TASK_STARTUP_NAME, "FreeRTOS ");
sys_log_print_msg(tskKERNEL_VERSION_NUMBER);
@@ -92,8 +98,8 @@ void vTaskStartup(void)
/* TTC parameters */
ttc_data_buf.hw_version = 0x04;
- ttc_data_buf.fw_version = 0x00000400;
- ttc_data_buf.device_id = 0xCC2B;
+ ttc_data_buf.fw_version = 0x00000405;
+ ttc_data_buf.device_id = 0xCC2A + RADIO_MODULE;
#if defined(CONFIG_DEV_MEDIA_INT_ENABLED) && (CONFIG_DEV_MEDIA_INT_ENABLED == 1)
/* Internal non-volatile memory initialization */
@@ -163,10 +169,26 @@ void vTaskStartup(void)
}
#endif /* CONFIG_DEV_OBDH_ENABLED */
+ /* Checking and updating the reset counter parameter */
+ if (system_reset_count() == 0)
+ {
+ sys_log_print_event_from_module(SYS_LOG_INFO, TASK_STARTUP_NAME, "Reset counter: ");
+ sys_log_print_uint((uint32_t)(ttc_data_buf.reset_counter));
+ sys_log_new_line();
+ }
+ else
+ {
+ sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_STARTUP_NAME, "Failed to access last reset counter");
+ sys_log_new_line();
+ }
+
+
if (error_counter > 0U)
{
- sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_STARTUP_NAME, "Boot completed with ");
- sys_log_print_uint(error_counter);
+ sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_STARTUP_NAME, "TTC Radio Module ");
+ sys_log_print_uint((uint32_t)RADIO_MODULE);
+ sys_log_print_msg(" booted with ");
+ sys_log_print_uint((uint32_t)error_counter);
sys_log_print_msg(" ERROR(S)!");
sys_log_new_line();
@@ -174,7 +196,9 @@ void vTaskStartup(void)
}
else
{
- sys_log_print_event_from_module(SYS_LOG_INFO, TASK_STARTUP_NAME, "Boot completed with SUCCESS!");
+ sys_log_print_event_from_module(SYS_LOG_INFO, TASK_STARTUP_NAME, "Successfully booted TTC Radio Module ");
+ sys_log_print_uint((uint32_t)RADIO_MODULE);
+ sys_log_print_msg("!");
sys_log_new_line();
led_clear(LED_FAULT);
diff --git a/firmware/app/tasks/system_reset.c b/firmware/app/tasks/system_reset.c
index c1e1c283..13d103bc 100644
--- a/firmware/app/tasks/system_reset.c
+++ b/firmware/app/tasks/system_reset.c
@@ -24,10 +24,11 @@
* \brief Periodic system reset task implementation.
*
* \author Gabriel Mariano Marcelino
- *
- * \version 0.1.10
- *
- * \date 2020/01/12
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \addtogroup system_reset
* \{
@@ -38,13 +39,17 @@
#include "system_reset.h"
+#define pdMS_TO_TICKS_LONG( xTimeInMs ) ( ( TickType_t ) ( ( ( uint64_t ) ( xTimeInMs ) * ( uint64_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )
+
xTaskHandle xTaskSystemResetHandle;
void vTaskSystemReset(void)
{
+ TickType_t reset_period_ticks = pdMS_TO_TICKS_LONG((TickType_t) TASK_SYSTEM_RESET_PERIOD_MS);
+
while(1)
{
- vTaskDelay(pdMS_TO_TICKS(TASK_SYSTEM_RESET_PERIOD_MS));
+ vTaskDelay(pdMS_TO_TICKS_LONG(reset_period_ticks));
sys_log_print_event_from_module(SYS_LOG_INFO, TASK_SYSTEM_RESET_NAME, "Restarting the system...");
sys_log_new_line();
diff --git a/firmware/app/tasks/tasks.c b/firmware/app/tasks/tasks.c
index aceacd3b..2475a945 100644
--- a/firmware/app/tasks/tasks.c
+++ b/firmware/app/tasks/tasks.c
@@ -24,10 +24,11 @@
* \brief Tasks implementation.
*
* \author Gabriel Mariano Marcelino
- *
- * \version 0.4.3
- *
- * \date 2019/11/02
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \addtogroup tasks
* \{
@@ -45,7 +46,6 @@
#include "system_reset.h"
#include "radio_reset.h"
#include "read_sensors.h"
-#include "beacon.h"
#include "time_control.h"
#include "eps_server.h"
#include "obdh_server.h"
@@ -113,14 +113,6 @@ void create_tasks(void)
}
#endif /* CONFIG_TASK_READ_SENSORS_ENABLED */
-#if defined(CONFIG_TASK_BEACON_ENABLED) && (CONFIG_TASK_BEACON_ENABLED == 1)
- xTaskCreate(vTaskBeacon, TASK_BEACON_NAME, TASK_BEACON_STACK_SIZE, NULL, TASK_BEACON_PRIORITY, &xTaskBeaconHandle);
-
- if (xTaskBeaconHandle == NULL)
- {
- /* Error creating the beacon task */
- }
-#endif /* CONFIG_TASK_BEACON_ENABLED */
#if defined(CONFIG_TASK_TIME_CONTROL_ENABLED) && (CONFIG_TASK_TIME_CONTROL_ENABLED == 1)
xTaskCreate(vTaskTimeControl, TASK_TIME_CONTROL_NAME, TASK_TIME_CONTROL_STACK_SIZE, NULL, TASK_TIME_CONTROL_PRIORITY, &xTaskTimeControlHandle);
diff --git a/firmware/app/tasks/time_control.c b/firmware/app/tasks/time_control.c
index d45df57a..38975ea8 100644
--- a/firmware/app/tasks/time_control.c
+++ b/firmware/app/tasks/time_control.c
@@ -1,7 +1,7 @@
/*
* time_control.h
*
- * Copyright (C) 2021, SpaceLab.
+ * Copyright The TTC 2.0 Contributors.
*
* This file is part of TTC 2.0.
*
@@ -24,10 +24,11 @@
* \brief Time control task implementation.
*
* \author Gabriel Mariano Marcelino
- *
- * \version 0.1.10
- *
- * \date 2020/08/09
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \addtogroup time_control
* \{
@@ -115,11 +116,18 @@ void vTaskTimeControl(void)
if ((sys_tm % TIME_CONTROL_SAVE_PERIOD_SEC) == 0)
{
/* Save the current system time */
-// if (time_control_save_sys_time(sys_tm) != 0)
-// {
-// sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_TIME_CONTROL_NAME, "Error saving the system time!");
-// sys_log_new_line();
-// }
+ if (time_control_save_sys_time(sys_tm) != 0)
+ {
+ sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_TIME_CONTROL_NAME, "Error saving the system time!");
+ sys_log_new_line();
+ }
+ else
+ {
+ sys_log_print_event_from_module(SYS_LOG_INFO, TASK_TIME_CONTROL_NAME, "Saving system time (epoch): ");
+ sys_log_print_uint(sys_tm);
+ sys_log_print_msg(" sec");
+ sys_log_new_line();
+ }
}
vTaskDelayUntil(&last_cycle, pdMS_TO_TICKS(TASK_TIME_CONTROL_PERIOD_MS));
@@ -132,7 +140,7 @@ static int time_control_load_sys_time(sys_time_t *tm)
uint8_t buf[6] = {0};
- if (media_read(TIME_CONTROL_MEDIA, CONFIG_MEM_ADR_SYS_TIME, buf, 6U) == 0)
+ if (media_read(TIME_CONTROL_MEDIA, CONFIG_MEM_ADR_SYS_TIME, FLASH_SEG_A_ADR, buf, 6U) == 0)
{
if ((buf[0] == TIME_CONTROL_MEM_ID) && (time_control_crc8(buf, 5U) == buf[5]))
{
@@ -171,12 +179,15 @@ static int time_control_save_sys_time(sys_time_t tm)
buf[4] = (uint32_t)tm & 0xFFU;
buf[5] = time_control_crc8(buf, 5U);
- if (media_write(TIME_CONTROL_MEDIA, CONFIG_MEM_ADR_SYS_TIME, buf, 6U) != 0)
+ if (media_erase(TIME_CONTROL_MEDIA, FLASH_SEG_A_ADR) == 0)
{
- sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_TIME_CONTROL_NAME, "Error writing the system time to the non-volatile memory!");
- sys_log_new_line();
+ if (media_write(TIME_CONTROL_MEDIA, CONFIG_MEM_ADR_SYS_TIME, FLASH_SEG_A_ADR, buf, 6U) != 0)
+ {
+ sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_TIME_CONTROL_NAME, "Error writing the system time to the non-volatile memory!");
+ sys_log_new_line();
- err = -1;
+ err = -1;
+ }
}
return err;
diff --git a/firmware/app/tasks/uplink_manager.c b/firmware/app/tasks/uplink_manager.c
index b0f0161f..1d340529 100644
--- a/firmware/app/tasks/uplink_manager.c
+++ b/firmware/app/tasks/uplink_manager.c
@@ -25,9 +25,9 @@
*
* \author Miguel Boing
*
- * \version 0.4.5
+ * \version 1.0.0
*
- * \date 2023/04/03
+ * \date 2024/09/09
*
* \addtogroup uplink_manager
* \{
@@ -36,6 +36,7 @@
#include
#include
#include
+#include
#include "uplink_manager.h"
#include "startup.h"
@@ -53,22 +54,50 @@ void vTaskUplinkManager(void)
sys_log_print_event_from_module(SYS_LOG_INFO, TASK_UPLINK_MANAGER_NAME, "Initializing the Uplink Manager...");
sys_log_new_line();
- ttc_data_buf.radio.rx_fifo_counter = 0;
- ttc_data_buf.radio.rx_packet_counter = 0;
- ttc_data_buf.radio.last_rx_packet_bytes = &(ttc_data_buf.up_buf.packet_sizes);
+ ttc_data_buf.radio.rx_fifo_counter = 0U;
+ ttc_data_buf.radio.rx_packet_counter = 0U;
+ ttc_data_buf.radio.last_rx_packet_bytes = 0U;
- ttc_data_buf.up_buf.position_to_read = 0;
- ttc_data_buf.up_buf.position_to_write = 0;
+ ttc_data_buf.up_buf.position_to_read = 0U;
+ ttc_data_buf.up_buf.position_to_write = 0U;
- uint16_t rx_size = 230;
- uint8_t rx_packet[230];
- uint8_t pop_rx_packet[230];
+ uint8_t rx_packet[230] = {0};
+ uint8_t ngham_decoded_packet[220] = {0};
+ uint16_t ngham_decoded_packet_len = 0;
while(1)
{
TickType_t last_cycle = xTaskGetTickCount();
- /* TODO */
+ if (radio_available() == 0U)
+ {
+ sys_log_print_event_from_module(SYS_LOG_INFO, TASK_UPLINK_MANAGER_NAME, "Receiving a new package:");
+ sys_log_new_line();
+
+ if(radio_recv(rx_packet, 80U, 100U) > 0)
+ {
+ sys_log_print_event_from_module(SYS_LOG_INFO, TASK_UPLINK_MANAGER_NAME, "Decoding packet...");
+ sys_log_new_line();
+
+ if(ngham_decode(rx_packet, 220, ngham_decoded_packet, &ngham_decoded_packet_len) == 0)
+ {
+ uplink_add_packet(ngham_decoded_packet, ngham_decoded_packet_len);
+
+ sys_log_print_event_from_module(SYS_LOG_INFO, TASK_UPLINK_MANAGER_NAME, "Packet successfully received");
+ sys_log_new_line();
+ }
+ else
+ {
+ sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_UPLINK_MANAGER_NAME, "Failed to receive a new packet");
+ sys_log_new_line();
+ }
+ }
+ else
+ {
+ sys_log_print_event_from_module(SYS_LOG_ERROR, TASK_UPLINK_MANAGER_NAME, "Failed to receive a new packet");
+ sys_log_new_line();
+ }
+ }
vTaskDelayUntil(&last_cycle, pdMS_TO_TICKS(TASK_UPLINK_MANAGER_PERIOD_MS));
}
diff --git a/firmware/config/config.h b/firmware/config/config.h
index 394c9540..b08afb54 100644
--- a/firmware/config/config.h
+++ b/firmware/config/config.h
@@ -24,10 +24,11 @@
* \brief Configuration parameters definition.
*
* \author Gabriel Mariano Marcelino
- *
- * \version 0.4.5
- *
- * \date 2019/10/26
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \defgroup config Configuration
* \{
@@ -36,6 +37,9 @@
#ifndef CONFIG_H_
#define CONFIG_H_
+/* Targets the radio module, it can be '0' or '1'*/
+#define RADIO_MODULE -1
+
/* Tasks */
#define CONFIG_TASK_STARTUP_ENABLED 1
#define CONFIG_TASK_WATCHDOG_RESET_ENABLED 1
@@ -45,10 +49,10 @@
#define CONFIG_TASK_READ_SENSORS_ENABLED 1
#define CONFIG_TASK_BEACON_ENABLED 0
#define CONFIG_TASK_TIME_CONTROL_ENABLED 1
-#define CONFIG_TASK_EPS_SERVER_ENABLED 0
+#define CONFIG_TASK_EPS_SERVER_ENABLED RADIO_MODULE /* EPS Server is only available for module 1!*/
#define CONFIG_TASK_OBDH_SERVER_ENABLED 1
#define CONFIG_TASK_DOWNLINK_MANAGER_ENABLED 1
-#define CONFIG_TASK_UPLINK_MANAGER_ENABLED 0
+#define CONFIG_TASK_UPLINK_MANAGER_ENABLED 1
#define CONFIG_TASK_ANTENNA_DEPLOYMENT_ENABLED 1
#define CONFIG_TASK_READ_ANTENNA_ENABLED 0
diff --git a/firmware/config/radio_config_Si4463.h b/firmware/config/radio_0_config.h
similarity index 97%
rename from firmware/config/radio_config_Si4463.h
rename to firmware/config/radio_0_config.h
index c096d2cd..1c8fb11f 100644
--- a/firmware/config/radio_config_Si4463.h
+++ b/firmware/config/radio_0_config.h
@@ -21,7 +21,7 @@
/*
// Crys_freq(Hz): 30000000 Crys_tol(ppm): 10 IF_mode: 2 High_perf_Ch_Fil: 1 OSRtune: 0 Ch_Fil_Bw_AFC: 0 ANT_DIV: 0 PM_pattern: 0
// MOD_type: 3 Rsymb(sps): 4800 Fdev(Hz): 1200 RXBW(Hz): 150000 Manchester: 0 AFC_en: 0 Rsymb_error: 0.0 Chip-Version: 2
-// RF Freq.(MHz): 436.9 API_TC: 29 fhst: 0 inputBW: 0 BERT: 0 RAW_dout: 0 D_source: 0 Hi_pfm_div: 1
+// RF Freq.(MHz): 468.4 API_TC: 29 fhst: 0 inputBW: 0 BERT: 0 RAW_dout: 0 D_source: 0 Hi_pfm_div: 1
//
// # RX IF frequency is -468750 Hz
// # WB filter 3 (BW = 23.15 kHz); NB-filter 3 (BW = 23.15 kHz)
@@ -540,7 +540,7 @@
// FREQ_CONTROL_W_SIZE - Set window gating period (in number of crystal reference clock cycles) for counting VCO frequency during calibration.
// FREQ_CONTROL_VCOCNT_RX_ADJ - Adjust target count for VCO calibration in RX mode.
*/
-#define RF_FREQ_CONTROL_INTE_8 0x11, 0x40, 0x08, 0x00, 0x39, 0x0A, 0x06, 0xD3, 0x00, 0x00, 0x20, 0xFE
+#define RF_FREQ_CONTROL_INTE_8 0x11, 0x40, 0x08, 0x00, 0x3D, 0x0B, 0xA0, 0x6D, 0x00, 0x00, 0x20, 0xFE
// AUTOMATICALLY GENERATED CODE!
diff --git a/firmware/config/radio_1_config.h b/firmware/config/radio_1_config.h
new file mode 100644
index 00000000..9e307e6b
--- /dev/null
+++ b/firmware/config/radio_1_config.h
@@ -0,0 +1,632 @@
+/*! @file radio_config.h
+ * @brief This file contains the automatically generated
+ * configurations.
+ *
+ * @n WDS GUI Version: 3.2.11.0
+ * @n Device: Si4463 Rev.: B1
+ *
+ * @b COPYRIGHT
+ * @n Silicon Laboratories Confidential
+ * @n Copyright 2017 Silicon Laboratories, Inc.
+ * @n http://www.silabs.com
+ */
+
+#ifndef RADIO_CONFIG_H_
+#define RADIO_CONFIG_H_
+
+// USER DEFINED PARAMETERS
+// Define your own parameters here
+
+// INPUT DATA
+/*
+// Crys_freq(Hz): 30000000 Crys_tol(ppm): 10 IF_mode: 2 High_perf_Ch_Fil: 1 OSRtune: 0 Ch_Fil_Bw_AFC: 0 ANT_DIV: 0 PM_pattern: 0
+// MOD_type: 3 Rsymb(sps): 1200 Fdev(Hz): 300 RXBW(Hz): 150000 Manchester: 0 AFC_en: 0 Rsymb_error: 0.0 Chip-Version: 2
+// RF Freq.(MHz): 145.9 API_TC: 29 fhst: 0 inputBW: 0 BERT: 0 RAW_dout: 0 D_source: 0 Hi_pfm_div: 1
+//
+// # RX IF frequency is -468750 Hz
+// # WB filter 1 (BW = 7.15 kHz); NB-filter 1 (BW = 7.15 kHz)
+//
+// Modulation index: 0,5
+*/
+
+
+// CONFIGURATION PARAMETERS
+#define RADIO_CONFIGURATION_DATA_RADIO_XO_FREQ 30000000L
+#define RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER 0x00
+#define RADIO_CONFIGURATION_DATA_RADIO_PACKET_LENGTH 0x07
+#define RADIO_CONFIGURATION_DATA_RADIO_STATE_AFTER_POWER_UP 0x03
+#define RADIO_CONFIGURATION_DATA_RADIO_DELAY_CNT_AFTER_RESET 0xF000
+
+
+// CONFIGURATION COMMANDS
+
+/*
+// Command: RF_POWER_UP
+// Description: Command to power-up the device and select the operational mode and functionality.
+*/
+#define RF_POWER_UP 0x02, 0x01, 0x00, 0x01, 0xC9, 0xC3, 0x80
+
+/*
+// Command: RF_GPIO_PIN_CFG
+// Description: Configures the GPIO pins.
+*/
+#define RF_GPIO_PIN_CFG 0x13, 0x00, 0x63, 0x61, 0x60, 0x67, 0x4B, 0x00
+
+/*
+// Set properties: RF_GLOBAL_XO_TUNE_2
+// Number of properties: 2
+// Group ID: 0x00
+// Start ID: 0x00
+// Default values: 0x40, 0x00,
+// Descriptions:
+// GLOBAL_XO_TUNE - Configure the internal capacitor frequency tuning bank for the crystal oscillator.
+// GLOBAL_CLK_CFG - Clock configuration options.
+*/
+#define RF_GLOBAL_XO_TUNE_2 0x11, 0x00, 0x02, 0x00, 0x52, 0x00
+
+/*
+// Set properties: RF_GLOBAL_CONFIG_1
+// Number of properties: 1
+// Group ID: 0x00
+// Start ID: 0x03
+// Default values: 0x20,
+// Descriptions:
+// GLOBAL_CONFIG - Global configuration settings.
+*/
+#define RF_GLOBAL_CONFIG_1 0x11, 0x00, 0x01, 0x03, 0x60
+
+/*
+// Set properties: RF_INT_CTL_ENABLE_1
+// Number of properties: 1
+// Group ID: 0x01
+// Start ID: 0x00
+// Default values: 0x04,
+// Descriptions:
+// INT_CTL_ENABLE - This property provides for global enabling of the three interrupt groups (Chip, Modem and Packet Handler) in order to generate HW interrupts at the NIRQ pin.
+*/
+#define RF_INT_CTL_ENABLE_1 0x11, 0x01, 0x01, 0x00, 0x00
+
+/*
+// Set properties: RF_FRR_CTL_A_MODE_4
+// Number of properties: 4
+// Group ID: 0x02
+// Start ID: 0x00
+// Default values: 0x01, 0x02, 0x09, 0x00,
+// Descriptions:
+// FRR_CTL_A_MODE - Fast Response Register A Configuration.
+// FRR_CTL_B_MODE - Fast Response Register B Configuration.
+// FRR_CTL_C_MODE - Fast Response Register C Configuration.
+// FRR_CTL_D_MODE - Fast Response Register D Configuration.
+*/
+#define RF_FRR_CTL_A_MODE_4 0x11, 0x02, 0x04, 0x00, 0x01, 0x02, 0x03, 0x07
+
+/*
+// Set properties: RF_PREAMBLE_TX_LENGTH_9
+// Number of properties: 9
+// Group ID: 0x10
+// Start ID: 0x00
+// Default values: 0x08, 0x14, 0x00, 0x0F, 0x21, 0x00, 0x00, 0x00, 0x00,
+// Descriptions:
+// PREAMBLE_TX_LENGTH - Configure length of TX Preamble.
+// PREAMBLE_CONFIG_STD_1 - Configuration of reception of a packet with a Standard Preamble pattern.
+// PREAMBLE_CONFIG_NSTD - Configuration of transmission/reception of a packet with a Non-Standard Preamble pattern.
+// PREAMBLE_CONFIG_STD_2 - Configuration of timeout periods during reception of a packet with Standard Preamble pattern.
+// PREAMBLE_CONFIG - General configuration bits for the Preamble field.
+// PREAMBLE_PATTERN_31_24 - Configuration of the bit values describing a Non-Standard Preamble pattern.
+// PREAMBLE_PATTERN_23_16 - Configuration of the bit values describing a Non-Standard Preamble pattern.
+// PREAMBLE_PATTERN_15_8 - Configuration of the bit values describing a Non-Standard Preamble pattern.
+// PREAMBLE_PATTERN_7_0 - Configuration of the bit values describing a Non-Standard Preamble pattern.
+*/
+#define RF_PREAMBLE_TX_LENGTH_9 0x11, 0x10, 0x09, 0x00, 0x04, 0x14, 0x00, 0x0F, 0x31, 0x00, 0x00, 0x00, 0x00
+
+/*
+// Set properties: RF_SYNC_CONFIG_5
+// Number of properties: 5
+// Group ID: 0x11
+// Start ID: 0x00
+// Default values: 0x01, 0x2D, 0xD4, 0x2D, 0xD4,
+// Descriptions:
+// SYNC_CONFIG - Sync Word configuration bits.
+// SYNC_BITS_31_24 - Sync word.
+// SYNC_BITS_23_16 - Sync word.
+// SYNC_BITS_15_8 - Sync word.
+// SYNC_BITS_7_0 - Sync word.
+*/
+#define RF_SYNC_CONFIG_5 0x11, 0x11, 0x05, 0x00, 0x03, 0xBA, 0x67, 0x54, 0x7E
+
+/*
+// Set properties: RF_PKT_CRC_CONFIG_7
+// Number of properties: 7
+// Group ID: 0x12
+// Start ID: 0x00
+// Default values: 0x00, 0x01, 0x08, 0xFF, 0xFF, 0x00, 0x00,
+// Descriptions:
+// PKT_CRC_CONFIG - Select a CRC polynomial and seed.
+// PKT_WHT_POLY_15_8 - 16-bit polynomial value for the PN Generator (e.g., for Data Whitening)
+// PKT_WHT_POLY_7_0 - 16-bit polynomial value for the PN Generator (e.g., for Data Whitening)
+// PKT_WHT_SEED_15_8 - 16-bit seed value for the PN Generator (e.g., for Data Whitening)
+// PKT_WHT_SEED_7_0 - 16-bit seed value for the PN Generator (e.g., for Data Whitening)
+// PKT_WHT_BIT_NUM - Selects which bit of the LFSR (used to generate the PN / data whitening sequence) is used as the output bit for data scrambling.
+// PKT_CONFIG1 - General configuration bits for transmission or reception of a packet.
+*/
+#define RF_PKT_CRC_CONFIG_7 0x11, 0x12, 0x07, 0x00, 0x80, 0x01, 0x08, 0xFF, 0xFF, 0x00, 0x02
+
+/*
+// Set properties: RF_PKT_LEN_12
+// Number of properties: 12
+// Group ID: 0x12
+// Start ID: 0x08
+// Default values: 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+// Descriptions:
+// PKT_LEN - Configuration bits for reception of a variable length packet.
+// PKT_LEN_FIELD_SOURCE - Field number containing the received packet length byte(s).
+// PKT_LEN_ADJUST - Provides for adjustment/offset of the received packet length value (in order to accommodate a variety of methods of defining total packet length).
+// PKT_TX_THRESHOLD - TX FIFO almost empty threshold.
+// PKT_RX_THRESHOLD - RX FIFO Almost Full threshold.
+// PKT_FIELD_1_LENGTH_12_8 - Unsigned 13-bit Field 1 length value.
+// PKT_FIELD_1_LENGTH_7_0 - Unsigned 13-bit Field 1 length value.
+// PKT_FIELD_1_CONFIG - General data processing and packet configuration bits for Field 1.
+// PKT_FIELD_1_CRC_CONFIG - Configuration of CRC control bits across Field 1.
+// PKT_FIELD_2_LENGTH_12_8 - Unsigned 13-bit Field 2 length value.
+// PKT_FIELD_2_LENGTH_7_0 - Unsigned 13-bit Field 2 length value.
+// PKT_FIELD_2_CONFIG - General data processing and packet configuration bits for Field 2.
+*/
+#define RF_PKT_LEN_12 0x11, 0x12, 0x0C, 0x08, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x32, 0x04, 0x00, 0x00, 0x00, 0x00
+
+/*
+// Set properties: RF_PKT_FIELD_2_CRC_CONFIG_12
+// Number of properties: 12
+// Group ID: 0x12
+// Start ID: 0x14
+// Default values: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+// Descriptions:
+// PKT_FIELD_2_CRC_CONFIG - Configuration of CRC control bits across Field 2.
+// PKT_FIELD_3_LENGTH_12_8 - Unsigned 13-bit Field 3 length value.
+// PKT_FIELD_3_LENGTH_7_0 - Unsigned 13-bit Field 3 length value.
+// PKT_FIELD_3_CONFIG - General data processing and packet configuration bits for Field 3.
+// PKT_FIELD_3_CRC_CONFIG - Configuration of CRC control bits across Field 3.
+// PKT_FIELD_4_LENGTH_12_8 - Unsigned 13-bit Field 4 length value.
+// PKT_FIELD_4_LENGTH_7_0 - Unsigned 13-bit Field 4 length value.
+// PKT_FIELD_4_CONFIG - General data processing and packet configuration bits for Field 4.
+// PKT_FIELD_4_CRC_CONFIG - Configuration of CRC control bits across Field 4.
+// PKT_FIELD_5_LENGTH_12_8 - Unsigned 13-bit Field 5 length value.
+// PKT_FIELD_5_LENGTH_7_0 - Unsigned 13-bit Field 5 length value.
+// PKT_FIELD_5_CONFIG - General data processing and packet configuration bits for Field 5.
+*/
+#define RF_PKT_FIELD_2_CRC_CONFIG_12 0x11, 0x12, 0x0C, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+/*
+// Set properties: RF_PKT_FIELD_5_CRC_CONFIG_12
+// Number of properties: 12
+// Group ID: 0x12
+// Start ID: 0x20
+// Default values: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+// Descriptions:
+// PKT_FIELD_5_CRC_CONFIG - Configuration of CRC control bits across Field 5.
+// PKT_RX_FIELD_1_LENGTH_12_8 - Unsigned 13-bit RX Field 1 length value.
+// PKT_RX_FIELD_1_LENGTH_7_0 - Unsigned 13-bit RX Field 1 length value.
+// PKT_RX_FIELD_1_CONFIG - General data processing and packet configuration bits for RX Field 1.
+// PKT_RX_FIELD_1_CRC_CONFIG - Configuration of CRC control bits across RX Field 1.
+// PKT_RX_FIELD_2_LENGTH_12_8 - Unsigned 13-bit RX Field 2 length value.
+// PKT_RX_FIELD_2_LENGTH_7_0 - Unsigned 13-bit RX Field 2 length value.
+// PKT_RX_FIELD_2_CONFIG - General data processing and packet configuration bits for RX Field 2.
+// PKT_RX_FIELD_2_CRC_CONFIG - Configuration of CRC control bits across RX Field 2.
+// PKT_RX_FIELD_3_LENGTH_12_8 - Unsigned 13-bit RX Field 3 length value.
+// PKT_RX_FIELD_3_LENGTH_7_0 - Unsigned 13-bit RX Field 3 length value.
+// PKT_RX_FIELD_3_CONFIG - General data processing and packet configuration bits for RX Field 3.
+*/
+#define RF_PKT_FIELD_5_CRC_CONFIG_12 0x11, 0x12, 0x0C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+/*
+// Set properties: RF_PKT_RX_FIELD_3_CRC_CONFIG_9
+// Number of properties: 9
+// Group ID: 0x12
+// Start ID: 0x2C
+// Default values: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+// Descriptions:
+// PKT_RX_FIELD_3_CRC_CONFIG - Configuration of CRC control bits across RX Field 3.
+// PKT_RX_FIELD_4_LENGTH_12_8 - Unsigned 13-bit RX Field 4 length value.
+// PKT_RX_FIELD_4_LENGTH_7_0 - Unsigned 13-bit RX Field 4 length value.
+// PKT_RX_FIELD_4_CONFIG - General data processing and packet configuration bits for RX Field 4.
+// PKT_RX_FIELD_4_CRC_CONFIG - Configuration of CRC control bits across RX Field 4.
+// PKT_RX_FIELD_5_LENGTH_12_8 - Unsigned 13-bit RX Field 5 length value.
+// PKT_RX_FIELD_5_LENGTH_7_0 - Unsigned 13-bit RX Field 5 length value.
+// PKT_RX_FIELD_5_CONFIG - General data processing and packet configuration bits for RX Field 5.
+// PKT_RX_FIELD_5_CRC_CONFIG - Configuration of CRC control bits across RX Field 5.
+*/
+#define RF_PKT_RX_FIELD_3_CRC_CONFIG_9 0x11, 0x12, 0x09, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+/*
+// Set properties: RF_MODEM_MOD_TYPE_12
+// Number of properties: 12
+// Group ID: 0x20
+// Start ID: 0x00
+// Default values: 0x02, 0x80, 0x07, 0x0F, 0x42, 0x40, 0x01, 0xC9, 0xC3, 0x80, 0x00, 0x06,
+// Descriptions:
+// MODEM_MOD_TYPE - Selects the type of modulation. In TX mode, additionally selects the source of the modulation.
+// MODEM_MAP_CONTROL - Controls polarity and mapping of transmit and receive bits.
+// MODEM_DSM_CTRL - Miscellaneous control bits for the Delta-Sigma Modulator (DSM) in the PLL Synthesizer.
+// MODEM_DATA_RATE_2 - Unsigned 24-bit value used to determine the TX data rate
+// MODEM_DATA_RATE_1 - Unsigned 24-bit value used to determine the TX data rate
+// MODEM_DATA_RATE_0 - Unsigned 24-bit value used to determine the TX data rate
+// MODEM_TX_NCO_MODE_3 - TX Gaussian filter oversampling ratio and Byte 3 of unsigned 26-bit TX Numerically Controlled Oscillator (NCO) modulus.
+// MODEM_TX_NCO_MODE_2 - TX Gaussian filter oversampling ratio and Byte 3 of unsigned 26-bit TX Numerically Controlled Oscillator (NCO) modulus.
+// MODEM_TX_NCO_MODE_1 - TX Gaussian filter oversampling ratio and Byte 3 of unsigned 26-bit TX Numerically Controlled Oscillator (NCO) modulus.
+// MODEM_TX_NCO_MODE_0 - TX Gaussian filter oversampling ratio and Byte 3 of unsigned 26-bit TX Numerically Controlled Oscillator (NCO) modulus.
+// MODEM_FREQ_DEV_2 - 17-bit unsigned TX frequency deviation word.
+// MODEM_FREQ_DEV_1 - 17-bit unsigned TX frequency deviation word.
+*/
+#define RF_MODEM_MOD_TYPE_12 0x11, 0x20, 0x0C, 0x00, 0x03, 0x00, 0x07, 0x00, 0xBB, 0x80, 0x05, 0xC9, 0xC3, 0x80, 0x00, 0x00
+
+/*
+// Set properties: RF_MODEM_FREQ_DEV_0_1
+// Number of properties: 1
+// Group ID: 0x20
+// Start ID: 0x0C
+// Default values: 0xD3,
+// Descriptions:
+// MODEM_FREQ_DEV_0 - 17-bit unsigned TX frequency deviation word.
+*/
+#define RF_MODEM_FREQ_DEV_0_1 0x11, 0x20, 0x01, 0x0C, 0x3F
+
+/*
+// Set properties: RF_MODEM_TX_RAMP_DELAY_8
+// Number of properties: 8
+// Group ID: 0x20
+// Start ID: 0x18
+// Default values: 0x01, 0x00, 0x08, 0x03, 0xC0, 0x00, 0x10, 0x20,
+// Descriptions:
+// MODEM_TX_RAMP_DELAY - TX ramp-down delay setting.
+// MODEM_MDM_CTRL - MDM control.
+// MODEM_IF_CONTROL - Selects Fixed-IF, Scaled-IF, or Zero-IF mode of RX Modem operation.
+// MODEM_IF_FREQ_2 - the IF frequency setting (an 18-bit signed number).
+// MODEM_IF_FREQ_1 - the IF frequency setting (an 18-bit signed number).
+// MODEM_IF_FREQ_0 - the IF frequency setting (an 18-bit signed number).
+// MODEM_DECIMATION_CFG1 - Specifies three decimator ratios for the Cascaded Integrator Comb (CIC) filter.
+// MODEM_DECIMATION_CFG0 - Specifies miscellaneous parameters and decimator ratios for the Cascaded Integrator Comb (CIC) filter.
+*/
+#define RF_MODEM_TX_RAMP_DELAY_8 0x11, 0x20, 0x08, 0x18, 0x01, 0x00, 0x08, 0x02, 0x80, 0x00, 0xF0, 0x20
+
+/*
+// Set properties: RF_MODEM_BCR_OSR_1_9
+// Number of properties: 9
+// Group ID: 0x20
+// Start ID: 0x22
+// Default values: 0x00, 0x4B, 0x06, 0xD3, 0xA0, 0x06, 0xD3, 0x02, 0xC0,
+// Descriptions:
+// MODEM_BCR_OSR_1 - RX BCR/Slicer oversampling rate (12-bit unsigned number).
+// MODEM_BCR_OSR_0 - RX BCR/Slicer oversampling rate (12-bit unsigned number).
+// MODEM_BCR_NCO_OFFSET_2 - RX BCR NCO offset value (an unsigned 22-bit number).
+// MODEM_BCR_NCO_OFFSET_1 - RX BCR NCO offset value (an unsigned 22-bit number).
+// MODEM_BCR_NCO_OFFSET_0 - RX BCR NCO offset value (an unsigned 22-bit number).
+// MODEM_BCR_GAIN_1 - The unsigned 11-bit RX BCR loop gain value.
+// MODEM_BCR_GAIN_0 - The unsigned 11-bit RX BCR loop gain value.
+// MODEM_BCR_GEAR - RX BCR loop gear control.
+// MODEM_BCR_MISC1 - Miscellaneous control bits for the RX BCR loop.
+*/
+#define RF_MODEM_BCR_OSR_1_9 0x11, 0x20, 0x09, 0x22, 0x00, 0xC3, 0x02, 0x9F, 0x17, 0x05, 0x40, 0x02, 0x00
+
+/*
+// Set properties: RF_MODEM_AFC_GEAR_7
+// Number of properties: 7
+// Group ID: 0x20
+// Start ID: 0x2C
+// Default values: 0x00, 0x23, 0x83, 0x69, 0x00, 0x40, 0xA0,
+// Descriptions:
+// MODEM_AFC_GEAR - RX AFC loop gear control.
+// MODEM_AFC_WAIT - RX AFC loop wait time control.
+// MODEM_AFC_GAIN_1 - Sets the gain of the PLL-based AFC acquisition loop, and provides miscellaneous control bits for AFC functionality.
+// MODEM_AFC_GAIN_0 - Sets the gain of the PLL-based AFC acquisition loop, and provides miscellaneous control bits for AFC functionality.
+// MODEM_AFC_LIMITER_1 - Set the AFC limiter value.
+// MODEM_AFC_LIMITER_0 - Set the AFC limiter value.
+// MODEM_AFC_MISC - Specifies miscellaneous AFC control bits.
+*/
+#define RF_MODEM_AFC_GEAR_7 0x11, 0x20, 0x07, 0x2C, 0x00, 0x12, 0x80, 0x1F, 0x05, 0x52, 0xA0
+
+/*
+// Set properties: RF_MODEM_AGC_CONTROL_1
+// Number of properties: 1
+// Group ID: 0x20
+// Start ID: 0x35
+// Default values: 0xE0,
+// Descriptions:
+// MODEM_AGC_CONTROL - Miscellaneous control bits for the Automatic Gain Control (AGC) function in the RX Chain.
+*/
+#define RF_MODEM_AGC_CONTROL_1 0x11, 0x20, 0x01, 0x35, 0xE2
+
+/*
+// Set properties: RF_MODEM_AGC_WINDOW_SIZE_9
+// Number of properties: 9
+// Group ID: 0x20
+// Start ID: 0x38
+// Default values: 0x11, 0x10, 0x10, 0x0B, 0x1C, 0x40, 0x00, 0x00, 0x2B,
+// Descriptions:
+// MODEM_AGC_WINDOW_SIZE - Specifies the size of the measurement and settling windows for the AGC algorithm.
+// MODEM_AGC_RFPD_DECAY - Sets the decay time of the RF peak detectors.
+// MODEM_AGC_IFPD_DECAY - Sets the decay time of the IF peak detectors.
+// MODEM_FSK4_GAIN1 - Specifies the gain factor of the secondary branch in 4(G)FSK ISI-suppression.
+// MODEM_FSK4_GAIN0 - Specifies the gain factor of the primary branch in 4(G)FSK ISI-suppression.
+// MODEM_FSK4_TH1 - 16 bit 4(G)FSK slicer threshold.
+// MODEM_FSK4_TH0 - 16 bit 4(G)FSK slicer threshold.
+// MODEM_FSK4_MAP - 4(G)FSK symbol mapping code.
+// MODEM_OOK_PDTC - Configures the attack and decay times of the OOK Peak Detector.
+*/
+#define RF_MODEM_AGC_WINDOW_SIZE_9 0x11, 0x20, 0x09, 0x38, 0x11, 0x2B, 0x2B, 0x00, 0x1A, 0x20, 0x00, 0x00, 0x29
+
+/*
+// Set properties: RF_MODEM_OOK_CNT1_9
+// Number of properties: 9
+// Group ID: 0x20
+// Start ID: 0x42
+// Default values: 0xA4, 0x03, 0x56, 0x02, 0x00, 0xA3, 0x02, 0x80, 0xFF,
+// Descriptions:
+// MODEM_OOK_CNT1 - OOK control.
+// MODEM_OOK_MISC - Selects the detector(s) used for demodulation of an OOK signal, or for demodulation of a (G)FSK signal when using the asynchronous demodulator.
+// MODEM_RAW_SEARCH - Defines and controls the search period length for the Moving Average and Min-Max detectors.
+// MODEM_RAW_CONTROL - Defines gain and enable controls for raw / nonstandard mode.
+// MODEM_RAW_EYE_1 - 11 bit eye-open detector threshold.
+// MODEM_RAW_EYE_0 - 11 bit eye-open detector threshold.
+// MODEM_ANT_DIV_MODE - Antenna diversity mode settings.
+// MODEM_ANT_DIV_CONTROL - Specifies controls for the Antenna Diversity algorithm.
+// MODEM_RSSI_THRESH - Configures the RSSI threshold.
+*/
+#define RF_MODEM_OOK_CNT1_9 0x11, 0x20, 0x09, 0x42, 0xA4, 0x03, 0xD6, 0x03, 0x00, 0x31, 0x01, 0x80, 0xFF
+
+/*
+// Set properties: RF_MODEM_RSSI_CONTROL_1
+// Number of properties: 1
+// Group ID: 0x20
+// Start ID: 0x4C
+// Default values: 0x01,
+// Descriptions:
+// MODEM_RSSI_CONTROL - Control of the averaging modes and latching time for reporting RSSI value(s).
+*/
+#define RF_MODEM_RSSI_CONTROL_1 0x11, 0x20, 0x01, 0x4C, 0x00
+
+/*
+// Set properties: RF_MODEM_RSSI_COMP_1
+// Number of properties: 1
+// Group ID: 0x20
+// Start ID: 0x4E
+// Default values: 0x32,
+// Descriptions:
+// MODEM_RSSI_COMP - RSSI compensation value.
+*/
+#define RF_MODEM_RSSI_COMP_1 0x11, 0x20, 0x01, 0x4E, 0x40
+
+/*
+// Set properties: RF_MODEM_CLKGEN_BAND_1
+// Number of properties: 1
+// Group ID: 0x20
+// Start ID: 0x51
+// Default values: 0x08,
+// Descriptions:
+// MODEM_CLKGEN_BAND - Select PLL Synthesizer output divider ratio as a function of frequency band.
+*/
+#define RF_MODEM_CLKGEN_BAND_1 0x11, 0x20, 0x01, 0x51, 0x0D
+
+/*
+// Set properties: RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12
+// Number of properties: 12
+// Group ID: 0x21
+// Start ID: 0x00
+// Default values: 0xFF, 0xBA, 0x0F, 0x51, 0xCF, 0xA9, 0xC9, 0xFC, 0x1B, 0x1E, 0x0F, 0x01,
+// Descriptions:
+// MODEM_CHFLT_RX1_CHFLT_COE13_7_0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COE12_7_0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COE11_7_0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COE10_7_0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COE9_7_0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COE8_7_0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COE7_7_0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COE6_7_0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COE5_7_0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COE4_7_0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COE3_7_0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COE2_7_0 - Filter coefficients for the first set of RX filter coefficients.
+*/
+#define RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12 0x11, 0x21, 0x0C, 0x00, 0xFF, 0xBA, 0x0F, 0x51, 0xCF, 0xA9, 0xC9, 0xFC, 0x1B, 0x1E, 0x0F, 0x01
+
+/*
+// Set properties: RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12
+// Number of properties: 12
+// Group ID: 0x21
+// Start ID: 0x0C
+// Default values: 0xFC, 0xFD, 0x15, 0xFF, 0x00, 0x0F, 0xFF, 0xC4, 0x30, 0x7F, 0xF5, 0xB5,
+// Descriptions:
+// MODEM_CHFLT_RX1_CHFLT_COE1_7_0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COE0_7_0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COEM0 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COEM1 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COEM2 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX1_CHFLT_COEM3 - Filter coefficients for the first set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COE13_7_0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COE12_7_0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COE11_7_0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COE10_7_0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COE9_7_0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COE8_7_0 - Filter coefficients for the second set of RX filter coefficients.
+*/
+#define RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12 0x11, 0x21, 0x0C, 0x0C, 0xFC, 0xFD, 0x15, 0xFF, 0x00, 0x0F, 0xFF, 0xBA, 0x0F, 0x51, 0xCF, 0xA9
+
+/*
+// Set properties: RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12
+// Number of properties: 12
+// Group ID: 0x21
+// Start ID: 0x18
+// Default values: 0xB8, 0xDE, 0x05, 0x17, 0x16, 0x0C, 0x03, 0x00, 0x15, 0xFF, 0x00, 0x00,
+// Descriptions:
+// MODEM_CHFLT_RX2_CHFLT_COE7_7_0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COE6_7_0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COE5_7_0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COE4_7_0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COE3_7_0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COE2_7_0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COE1_7_0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COE0_7_0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COEM0 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COEM1 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COEM2 - Filter coefficients for the second set of RX filter coefficients.
+// MODEM_CHFLT_RX2_CHFLT_COEM3 - Filter coefficients for the second set of RX filter coefficients.
+*/
+#define RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12 0x11, 0x21, 0x0C, 0x18, 0xC9, 0xFC, 0x1B, 0x1E, 0x0F, 0x01, 0xFC, 0xFD, 0x15, 0xFF, 0x00, 0x0F
+
+/*
+// Set properties: RF_PA_MODE_4
+// Number of properties: 4
+// Group ID: 0x22
+// Start ID: 0x00
+// Default values: 0x08, 0x7F, 0x00, 0x5D,
+// Descriptions:
+// PA_MODE - Selects the PA operating mode, and selects resolution of PA power adjustment (i.e., step size).
+// PA_PWR_LVL - Configuration of PA output power level.
+// PA_BIAS_CLKDUTY - Configuration of the PA Bias and duty cycle of the TX clock source.
+// PA_TC - Configuration of PA ramping parameters.
+*/
+#define RF_PA_MODE_4 0x11, 0x22, 0x04, 0x00, 0x08, 0x7F, 0x00, 0x3D
+
+/*
+// Set properties: RF_SYNTH_PFDCP_CPFF_7
+// Number of properties: 7
+// Group ID: 0x23
+// Start ID: 0x00
+// Default values: 0x2C, 0x0E, 0x0B, 0x04, 0x0C, 0x73, 0x03,
+// Descriptions:
+// SYNTH_PFDCP_CPFF - Feed forward charge pump current selection.
+// SYNTH_PFDCP_CPINT - Integration charge pump current selection.
+// SYNTH_VCO_KV - Gain scaling factors (Kv) for the VCO tuning varactors on both the integrated-path and feed forward path.
+// SYNTH_LPFILT3 - Value of resistor R2 in feed-forward path of loop filter.
+// SYNTH_LPFILT2 - Value of capacitor C2 in feed-forward path of loop filter.
+// SYNTH_LPFILT1 - Value of capacitors C1 and C3 in feed-forward path of loop filter.
+// SYNTH_LPFILT0 - Bias current of the active amplifier in the feed-forward loop filter.
+*/
+#define RF_SYNTH_PFDCP_CPFF_7 0x11, 0x23, 0x07, 0x00, 0x2C, 0x0E, 0x0B, 0x04, 0x0C, 0x73, 0x03
+
+/*
+// Set properties: RF_MATCH_VALUE_1_12
+// Number of properties: 12
+// Group ID: 0x30
+// Start ID: 0x00
+// Default values: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+// Descriptions:
+// MATCH_VALUE_1 - Match value to be compared with the result of logically AND-ing (bit-wise) the Mask 1 value with the received Match 1 byte.
+// MATCH_MASK_1 - Mask value to be logically AND-ed (bit-wise) with the Match 1 byte.
+// MATCH_CTRL_1 - Enable for Packet Match functionality, and configuration of Match Byte 1.
+// MATCH_VALUE_2 - Match value to be compared with the result of logically AND-ing (bit-wise) the Mask 2 value with the received Match 2 byte.
+// MATCH_MASK_2 - Mask value to be logically AND-ed (bit-wise) with the Match 2 byte.
+// MATCH_CTRL_2 - Configuration of Match Byte 2.
+// MATCH_VALUE_3 - Match value to be compared with the result of logically AND-ing (bit-wise) the Mask 3 value with the received Match 3 byte.
+// MATCH_MASK_3 - Mask value to be logically AND-ed (bit-wise) with the Match 3 byte.
+// MATCH_CTRL_3 - Configuration of Match Byte 3.
+// MATCH_VALUE_4 - Match value to be compared with the result of logically AND-ing (bit-wise) the Mask 4 value with the received Match 4 byte.
+// MATCH_MASK_4 - Mask value to be logically AND-ed (bit-wise) with the Match 4 byte.
+// MATCH_CTRL_4 - Configuration of Match Byte 4.
+*/
+#define RF_MATCH_VALUE_1_12 0x11, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+/*
+// Set properties: RF_FREQ_CONTROL_INTE_8
+// Number of properties: 8
+// Group ID: 0x40
+// Start ID: 0x00
+// Default values: 0x3C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFF,
+// Descriptions:
+// FREQ_CONTROL_INTE - Frac-N PLL Synthesizer integer divide number.
+// FREQ_CONTROL_FRAC_2 - Frac-N PLL fraction number.
+// FREQ_CONTROL_FRAC_1 - Frac-N PLL fraction number.
+// FREQ_CONTROL_FRAC_0 - Frac-N PLL fraction number.
+// FREQ_CONTROL_CHANNEL_STEP_SIZE_1 - EZ Frequency Programming channel step size.
+// FREQ_CONTROL_CHANNEL_STEP_SIZE_0 - EZ Frequency Programming channel step size.
+// FREQ_CONTROL_W_SIZE - Set window gating period (in number of crystal reference clock cycles) for counting VCO frequency during calibration.
+// FREQ_CONTROL_VCOCNT_RX_ADJ - Adjust target count for VCO calibration in RX mode.
+*/
+#define RF_FREQ_CONTROL_INTE_8 0x11, 0x40, 0x08, 0x00, 0x39, 0x0A, 0xE1, 0x47, 0x00, 0x00, 0x20, 0xFA
+
+
+// AUTOMATICALLY GENERATED CODE!
+// DO NOT EDIT/MODIFY BELOW THIS LINE!
+// --------------------------------------------
+
+#ifndef FIRMWARE_LOAD_COMPILE
+#define RADIO_CONFIGURATION_DATA_ARRAY { \
+ 0x07, RF_POWER_UP, \
+ 0x08, RF_GPIO_PIN_CFG, \
+ 0x06, RF_GLOBAL_XO_TUNE_2, \
+ 0x05, RF_GLOBAL_CONFIG_1, \
+ 0x05, RF_INT_CTL_ENABLE_1, \
+ 0x08, RF_FRR_CTL_A_MODE_4, \
+ 0x0D, RF_PREAMBLE_TX_LENGTH_9, \
+ 0x09, RF_SYNC_CONFIG_5, \
+ 0x0B, RF_PKT_CRC_CONFIG_7, \
+ 0x10, RF_PKT_LEN_12, \
+ 0x10, RF_PKT_FIELD_2_CRC_CONFIG_12, \
+ 0x10, RF_PKT_FIELD_5_CRC_CONFIG_12, \
+ 0x0D, RF_PKT_RX_FIELD_3_CRC_CONFIG_9, \
+ 0x10, RF_MODEM_MOD_TYPE_12, \
+ 0x05, RF_MODEM_FREQ_DEV_0_1, \
+ 0x0C, RF_MODEM_TX_RAMP_DELAY_8, \
+ 0x0D, RF_MODEM_BCR_OSR_1_9, \
+ 0x0B, RF_MODEM_AFC_GEAR_7, \
+ 0x05, RF_MODEM_AGC_CONTROL_1, \
+ 0x0D, RF_MODEM_AGC_WINDOW_SIZE_9, \
+ 0x0D, RF_MODEM_OOK_CNT1_9, \
+ 0x05, RF_MODEM_RSSI_CONTROL_1, \
+ 0x05, RF_MODEM_RSSI_COMP_1, \
+ 0x05, RF_MODEM_CLKGEN_BAND_1, \
+ 0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12, \
+ 0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12, \
+ 0x10, RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12, \
+ 0x08, RF_PA_MODE_4, \
+ 0x0B, RF_SYNTH_PFDCP_CPFF_7, \
+ 0x10, RF_MATCH_VALUE_1_12, \
+ 0x0C, RF_FREQ_CONTROL_INTE_8, \
+ 0x00 \
+ }
+#else
+#define RADIO_CONFIGURATION_DATA_ARRAY { 0 }
+#endif
+
+// DEFAULT VALUES FOR CONFIGURATION PARAMETERS
+#define RADIO_CONFIGURATION_DATA_RADIO_XO_FREQ_DEFAULT 30000000L
+#define RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER_DEFAULT 0x00
+#define RADIO_CONFIGURATION_DATA_RADIO_PACKET_LENGTH_DEFAULT 0x10
+#define RADIO_CONFIGURATION_DATA_RADIO_STATE_AFTER_POWER_UP_DEFAULT 0x01
+#define RADIO_CONFIGURATION_DATA_RADIO_DELAY_CNT_AFTER_RESET_DEFAULT 0x1000
+
+#define RADIO_CONFIGURATION_DATA_RADIO_PATCH_INCLUDED 0x00
+#define RADIO_CONFIGURATION_DATA_RADIO_PATCH_SIZE 0x00
+#define RADIO_CONFIGURATION_DATA_RADIO_PATCH { }
+
+#ifndef RADIO_CONFIGURATION_DATA_ARRAY
+#error "This property must be defined!"
+#endif
+
+#ifndef RADIO_CONFIGURATION_DATA_RADIO_XO_FREQ
+#define RADIO_CONFIGURATION_DATA_RADIO_XO_FREQ RADIO_CONFIGURATION_DATA_RADIO_XO_FREQ_DEFAULT
+#endif
+
+#ifndef RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER
+#define RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER_DEFAULT
+#endif
+
+#ifndef RADIO_CONFIGURATION_DATA_RADIO_PACKET_LENGTH
+#define RADIO_CONFIGURATION_DATA_RADIO_PACKET_LENGTH RADIO_CONFIGURATION_DATA_RADIO_PACKET_LENGTH_DEFAULT
+#endif
+
+#ifndef RADIO_CONFIGURATION_DATA_RADIO_STATE_AFTER_POWER_UP
+#define RADIO_CONFIGURATION_DATA_RADIO_STATE_AFTER_POWER_UP RADIO_CONFIGURATION_DATA_RADIO_STATE_AFTER_POWER_UP_DEFAULT
+#endif
+
+#ifndef RADIO_CONFIGURATION_DATA_RADIO_DELAY_CNT_AFTER_RESET
+#define RADIO_CONFIGURATION_DATA_RADIO_DELAY_CNT_AFTER_RESET RADIO_CONFIGURATION_DATA_RADIO_DELAY_CNT_AFTER_RESET_DEFAULT
+#endif
+
+#define RADIO_CONFIGURATION_DATA { \
+ Radio_Configuration_Data_Array, \
+ RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER, \
+ RADIO_CONFIGURATION_DATA_RADIO_PACKET_LENGTH, \
+ RADIO_CONFIGURATION_DATA_RADIO_STATE_AFTER_POWER_UP, \
+ RADIO_CONFIGURATION_DATA_RADIO_DELAY_CNT_AFTER_RESET \
+ }
+
+#endif /* RADIO_CONFIG_H_ */
diff --git a/firmware/config/si4463_revb1_framework.xml b/firmware/config/si4463_revb1_framework.xml
new file mode 100644
index 00000000..1babbd81
--- /dev/null
+++ b/firmware/config/si4463_revb1_framework.xml
@@ -0,0 +1,399 @@
+
+
+
+
+
+
+ 0
+
+
+ 468.40000
+
+
+ 0
+
+
+
+
+ False
+
+
+ 10.0
+
+
+ 10.0
+
+
+ 30
+
+
+ 82
+
+
+
+ False
+
+
+
+ 0
+
+
+
+
+ False
+
+
+ 29
+
+
+ 0
+
+
+ 127
+
+
+
+
+
+
+ 2
+
+
+ 4.800
+
+
+ 1.200
+
+
+ False
+
+
+ 150
+
+
+ 0
+
+
+ 0
+
+
+
+ 0
+
+
+ 0
+
+
+ False
+
+
+ 255
+
+
+
+
+ False
+
+
+ True
+
+
+
+ True
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+ 0
+
+
+
+
+ 48
+
+
+ 48
+
+
+ 1
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+
+
+ False
+
+
+
+
+
+ 0
+
+
+
+
+ True
+
+
+ False
+
+
+
+
+
+ 1
+
+
+ FF FF
+
+
+ 0
+
+
+
+
+
+ True
+
+
+ False
+
+
+
+
+ False
+
+
+ True
+
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+
+
+ 1
+
+
+ False
+
+
+ True
+
+
+
+ 4
+
+
+ 15
+
+
+ False
+
+
+ 20
+
+
+
+
+
+
+ 4
+
+
+ 0
+
+
+
+ 5D E6 2A 7E
+
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+ 7
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+ 7
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+ 7
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+ 7
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+ 50
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+
+
+
+ False
+
+
+ False
+ 0
+
+
+
+
+ False
+
+
+ False
+ 0
+
+
+
+
+ False
+
+
+ False
+ 0
+
+
+
+
+
+
+
+ 1
+
+
+ 3
+
+
+ 7
+
+
+ 2
+
+
+
+
+ False
+
+
+ DONOTHING
+
+
+ True
+
+
+ TX_FIFO_EMPTY
+
+
+ True
+
+
+ RX_STATE
+
+
+ True
+
+
+ TX_STATE
+
+
+ True
+
+
+ Active low interrupt signal
+
+
+ True
+
+
+ SDO
+
+
+ 0
+
+
+
+
+
\ No newline at end of file
diff --git a/firmware/devices/leds/leds.c b/firmware/devices/leds/leds.c
index 1d153494..d6c454b0 100644
--- a/firmware/devices/leds/leds.c
+++ b/firmware/devices/leds/leds.c
@@ -24,23 +24,34 @@
* \brief System LEDs implementation.
*
* \author Gabriel Mariano Marcelino
- *
- * \version 0.2.11
- *
- * \date 2020/01/20
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \addtogroup leds
* \{
*/
+#include
#include
#include
#include "leds.h"
/* GPIO configuration */
+/* TTC 2.0 Radio Module 0 has inverted silk screen labels, this is a manual firmware fix. */
+#if defined(RADIO_MODULE) && (RADIO_MODULE == 1)
#define LED_SYSTEM_PIN GPIO_PIN_28
#define LED_FAULT_PIN GPIO_PIN_27
+
+#else
+#define LED_SYSTEM_PIN GPIO_PIN_27
+#define LED_FAULT_PIN GPIO_PIN_28
+
+#endif
+
#define LED_DOWNLINK_PIN GPIO_PIN_30
#define LED_UPLINK_PIN GPIO_PIN_29
diff --git a/firmware/devices/media/media.c b/firmware/devices/media/media.c
index ac4b6ad4..e0c46986 100644
--- a/firmware/devices/media/media.c
+++ b/firmware/devices/media/media.c
@@ -24,10 +24,11 @@
* \brief Media device implementation.
*
* \author Gabriel Mariano Marcelino
- *
- * \version 0.1.19
- *
- * \date 2020/07/21
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \addtogroup media
* \{
@@ -60,60 +61,75 @@ int media_init(media_t med)
return err;
}
-int media_write(media_t med, uint32_t adr, uint8_t *data, uint16_t len)
+int media_write(media_t med, uint32_t adr, uint32_t sector, uint8_t *data, uint16_t len)
{
int err = -1;
+ uint16_t i = 0U;
switch(med)
{
case MEDIA_INT_FLASH:
{
- /* Address index */
- uint32_t adr_idx = adr + FLASH_SEG_A_ADR;
-
- uint16_t i = 0;
- for(i=0; i UINT8_MAX)
+ if (flash_mutex_take() == 0)
{
- sector_conv = UINT8_MAX;
+ if ((sector == FLASH_SEG_A_ADR) || (sector == FLASH_SEG_B_ADR))
+ {
+ flash_erase((uintptr_t)sector);
+ err = flash_mutex_give();
+ }
+ else
+ {
+ sys_log_print_event_from_module(SYS_LOG_ERROR, MEDIA_MODULE_NAME, "Erasing invalid sector!");
+ sys_log_new_line();
+ }
+
}
else
{
- sector_conv = (uint8_t)sector;
+ sys_log_print_event_from_module(SYS_LOG_ERROR, MEDIA_MODULE_NAME, "Couldn't get mutex control.");
+ sys_log_new_line();
}
- flash_write_single(0xFF, §or_conv);
-
- err = 0;
-
break;
- }
default:
sys_log_print_event_from_module(SYS_LOG_ERROR, MEDIA_MODULE_NAME, "Invalid storage media to erase!");
sys_log_new_line();
diff --git a/firmware/devices/media/media.h b/firmware/devices/media/media.h
index 7a4c0008..ade842ab 100644
--- a/firmware/devices/media/media.h
+++ b/firmware/devices/media/media.h
@@ -24,10 +24,11 @@
* \brief Media device definition.
*
* \author Gabriel Mariano Marcelino
- *
- * \version 0.1.19
- *
- * \date 2020/04/21
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \defgroup media Media
* \ingroup devices
@@ -39,6 +40,8 @@
#include
+#include
+
#define MEDIA_MODULE_NAME "Media"
/**
@@ -83,13 +86,15 @@ int media_init(media_t med);
*
* \param[in] adr is the address to write data.
*
+ * \param[in] sector is the sector number to write.
+ *
* \param[in] data is an array of bytes to write.
*
* \param[in] len is the number of bytes to write.
*
* \return The status/error code.
*/
-int media_write(media_t med, uint32_t adr, uint8_t *data, uint16_t len);
+int media_write(media_t med, uint32_t adr, uint32_t sector, uint8_t *data, uint16_t len);
/**
* \brief Reads data from a given address of a media device.
@@ -102,13 +107,15 @@ int media_write(media_t med, uint32_t adr, uint8_t *data, uint16_t len);
*
* \param[in] adr is the address to read.
*
+ * \param[in] sector is the sector number to read.
+ *
* \param[in,out] data is a pointer to store the read data.
*
* \param[in] len is the number of bytes to read starting at addr.
*
* \return The status/error code.
*/
-int media_read(media_t med, uint32_t adr, uint8_t *data, uint16_t len);
+int media_read(media_t med, uint32_t adr, uint32_t sector, uint8_t *data, uint16_t len);
/**
* \brief Erases a memory region from a media device.
@@ -131,7 +138,7 @@ int media_read(media_t med, uint32_t adr, uint8_t *data, uint16_t len);
*
* \return The status/error code.
*/
-int media_erase(media_t med, media_erase_t type, uint32_t sector);
+int media_erase(media_t med, uint32_t sector);
#endif /* MEDIA_H_ */
diff --git a/firmware/devices/obdh/obdh.c b/firmware/devices/obdh/obdh.c
index ed7aa374..f194c286 100644
--- a/firmware/devices/obdh/obdh.c
+++ b/firmware/devices/obdh/obdh.c
@@ -25,14 +25,16 @@
*
* \author Miguel Boing
*
- * \version 0.4.5
+ * \version 1.0.0
*
- * \date 2023/02/12
+ * \date 2024/09/11
*
* \addtogroup obdh
* \{
*/
+#include
+
#include
#include
@@ -73,11 +75,17 @@ int obdh_read_request(obdh_request_t *obdh_request)
int err = 0;
uint8_t request[7] = {0};
- spi_slave_dma_read(request, 7);
+ spi_slave_dma_read(request, 7U);
+ /*Check for preamble */
+ if (request[0] != 0x7EU)
+ {
+ err = -1;
+ spi_slave_dma_change_transfer_size(7U);
+ }
obdh_request->command = request[1];
- if ((obdh_request->command != 0xFF) && (obdh_request->command != 0x00)) /* Received a request */
+ if ((obdh_request->command != 0xFF) && (obdh_request->command != 0x00) && (err != -1)) /* Received a request */
{
switch(obdh_request->command)
{
@@ -96,14 +104,14 @@ int obdh_read_request(obdh_request_t *obdh_request)
sys_log_print_hex(obdh_request->parameter);
sys_log_new_line();
- if (obdh_request->parameter == CMDPR_PARAM_TX_ENABLE)
+ if ((obdh_request->parameter == CMDPR_PARAM_TX_ENABLE) || (obdh_request->parameter == CMDPR_PARAM_RESET_DEVICE))
{
obdh_request->data.param_8 = request[3];
}
else
{
sys_log_print_event_from_module(SYS_LOG_ERROR, OBDH_MODULE_NAME, "Unknown parameter:");
- sys_log_print_hex(request[3]);
+ sys_log_print_hex(request[2]);
sys_log_new_line();
err = -1;
@@ -114,26 +122,32 @@ int obdh_read_request(obdh_request_t *obdh_request)
obdh_request->data.data_packet.len = request[2];
- obdh_write_read_bytes(request[2]+2U);
+ spi_slave_dma_change_transfer_size((request[2] + 3U));
+
+ obdh_write_read_bytes((request[2] + 3U));
- vTaskDelay(pdMS_TO_TICKS(100));
+ vTaskDelay(pdMS_TO_TICKS(130));
- spi_slave_dma_read(obdh_request->data.data_packet.packet, (obdh_request->data.data_packet.len)+3);
+ spi_slave_dma_read(obdh_request->data.data_packet.packet, (obdh_request->data.data_packet.len + 3U));
- sys_log_print_event_from_module(SYS_LOG_INFO, OBDH_MODULE_NAME, "Transmit packet command received:");
+ /* Removing protocol bytes */
+ for (uint16_t i = 0; i < (uint16_t)(request[2]); i++)
+ {
+ obdh_request->data.data_packet.packet[i] = obdh_request->data.data_packet.packet[i+3U];
+ }
+
+ sys_log_print_event_from_module(SYS_LOG_INFO, OBDH_MODULE_NAME, "Transmit packet command received: ");
sys_log_print_uint(obdh_request->data.data_packet.len);
- sys_log_print_msg(" bytes.");
+ sys_log_print_msg(" bytes");
sys_log_new_line();
- sys_log_print_str("Packet: ");
- sys_log_dump_hex(&(obdh_request->data.data_packet.packet[3]), obdh_request->data.data_packet.len);
- sys_log_new_line();
+ spi_slave_dma_change_transfer_size(7U);
break;
case CMDPR_CMD_READ_FIRST_PACKET:
obdh_request->data.data_packet.len = request[2];
- sys_log_print_event_from_module(SYS_LOG_INFO, OBDH_MODULE_NAME, "Read packet command received.");
+ sys_log_print_event_from_module(SYS_LOG_INFO, OBDH_MODULE_NAME, "Read packet command received");
sys_log_new_line();
break;
@@ -282,7 +296,9 @@ int obdh_write_response_param(ttc_data_t *ttc_data_buf, obdh_response_t *obdh_re
break;
case CMDPR_PARAM_N_BYTES_FIRST_AV_RX:
- obdh_response->data.param_16 = *(ttc_data_buf->radio.last_rx_packet_bytes);
+ /* Update rx packet bytes */
+ ttc_data_buf->radio.last_rx_packet_bytes = ttc_data_buf->up_buf.packet_sizes[ttc_data_buf->up_buf.position_to_read];
+ obdh_response->data.param_16 = ttc_data_buf->radio.last_rx_packet_bytes;
break;
default:
@@ -307,27 +323,28 @@ int obdh_flush_request(obdh_request_t *obdh_request)
static int obdh_write_parameter(obdh_response_t *obdh_response)
{
int err = 0;
- uint8_t response[6] = {0};
+ uint8_t response[7] = {0};
- response[0] = obdh_response->command;
- response[1] = obdh_response->parameter;
+ response[0] = 0x7EU;
+ response[1] = obdh_response->command;
+ response[2] = obdh_response->parameter;
switch(cmdpr_param_size(obdh_response->parameter))
{
case 1:
- response[2] = obdh_response->data.param_8;
+ response[3] = obdh_response->data.param_8;
break;
case 2:
- response[2] = (uint8_t)((obdh_response->data.param_16 >> 8) & 0xFFU);
- response[3] = (uint8_t)(obdh_response->data.param_16 & 0xFFU);
+ response[3] = (uint8_t)((obdh_response->data.param_16 >> 8) & 0xFFU);
+ response[4] = (uint8_t)(obdh_response->data.param_16 & 0xFFU);
break;
case 4:
- response[2] = (uint8_t)((obdh_response->data.param_32 >> 24) & 0xFFU);
- response[3] = (uint8_t)((obdh_response->data.param_32 >> 16) & 0xFFU);
- response[4] = (uint8_t)((obdh_response->data.param_32 >> 8) & 0xFFU);
- response[5] = (uint8_t)(obdh_response->data.param_32 & 0xFFU);
+ response[3] = (uint8_t)((obdh_response->data.param_32 >> 24) & 0xFFU);
+ response[4] = (uint8_t)((obdh_response->data.param_32 >> 16) & 0xFFU);
+ response[5] = (uint8_t)((obdh_response->data.param_32 >> 8) & 0xFFU);
+ response[6] = (uint8_t)(obdh_response->data.param_32 & 0xFFU);
break;
default:
@@ -340,7 +357,7 @@ static int obdh_write_parameter(obdh_response_t *obdh_response)
if (err == 0)
{
- spi_slave_dma_write(response, 6);
+ spi_slave_dma_write(response, 7);
}
else
{
@@ -355,7 +372,9 @@ void obdh_write_read_bytes(uint16_t number_of_bytes) // cppcheck-suppress misra-
uint8_t buffer[230];
uint8_t i;
- for (i = 0U; i < 230U; i++)
+ buffer[0] = 0x7EU;
+
+ for (i = 1U; i < number_of_bytes; i++)
{
buffer[i] = 0x00U;
}
@@ -365,14 +384,33 @@ void obdh_write_read_bytes(uint16_t number_of_bytes) // cppcheck-suppress misra-
static int obdh_write_packet(obdh_response_t *obdh_response)
{
- int err = 0;
+ int err = -1;
+
+ uint8_t transmission_buffer[70U];
+ uint8_t transmission_buffer_p;
+
+ if((obdh_response->data.data_packet.len + 2) < 70U)
+ {
+ spi_slave_dma_change_transfer_size((obdh_response->data.data_packet.len + 2));
- spi_slave_dma_write(obdh_response->data.data_packet.packet, obdh_response->data.data_packet.len);
+ transmission_buffer[0] = 0x7EU;
+ transmission_buffer[1] = 0x04U;
- sys_log_print_str("Packet:");
+ for (transmission_buffer_p = 0U; transmission_buffer_p < obdh_response->data.data_packet.len; transmission_buffer_p++)
+ {
+ transmission_buffer[transmission_buffer_p + 2U] = obdh_response->data.data_packet.packet[transmission_buffer_p];
+ }
- sys_log_dump_hex(obdh_response->data.data_packet.packet, obdh_response->data.data_packet.len);
- sys_log_new_line();
+ spi_slave_dma_write(transmission_buffer, (obdh_response->data.data_packet.len + 2));
+
+ vTaskDelay(pdMS_TO_TICKS(130));
+
+ spi_slave_dma_read(NULL, (obdh_response->data.data_packet.len + 2));
+
+ spi_slave_dma_change_transfer_size(7U);
+
+ err = 0;
+ }
return err;
}
diff --git a/firmware/devices/radio/radio.c b/firmware/devices/radio/radio.c
index c2d70ef3..ef46ddfc 100644
--- a/firmware/devices/radio/radio.c
+++ b/firmware/devices/radio/radio.c
@@ -25,10 +25,10 @@
*
* \author Gabriel Mariano Marcelino
* \author Miguel Boing
- *
- * \version 0.4.5
- *
- * \date 2019/10/27
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \addtogroup radio
* \{
@@ -64,26 +64,36 @@ int radio_init(void)
int radio_send(uint8_t *data, uint16_t len)
{
- sys_log_print_event_from_module(SYS_LOG_INFO, RADIO_MODULE_NAME, "Transmitting ");
- sys_log_print_uint(len);
- sys_log_print_msg(" byte(s)...");
- sys_log_new_line();
-
int err = -1;
- led_set(LED_DOWNLINK);
-
- if(si446x_tx_long_packet(data, len))
+ if (si446x_mutex_take() == 0)
{
- led_clear(LED_DOWNLINK);
+ sys_log_print_event_from_module(SYS_LOG_INFO, RADIO_MODULE_NAME, "Transmitting ");
+ sys_log_print_uint(len);
+ sys_log_print_msg(" byte(s)...");
+ sys_log_new_line();
+
+ led_set(LED_DOWNLINK);
- if(si446x_rx_init())
+ if(si446x_tx_long_packet(data, len))
{
- err = 0;
+ led_clear(LED_DOWNLINK);
+
+ if(si446x_rx_init())
+ {
+ err = 0;
+ }
}
- }
- led_clear(LED_DOWNLINK);
+ led_clear(LED_DOWNLINK);
+
+ si446x_mutex_give();
+ }
+ else
+ {
+ sys_log_print_event_from_module(SYS_LOG_ERROR, RADIO_MODULE_NAME, "Couldn't get mutex control.");
+ sys_log_new_line();
+ }
return err;
}
@@ -94,20 +104,35 @@ int radio_recv(uint8_t *data, uint16_t len, uint32_t timeout_ms)
uint16_t i = 0;
- for(i = 0; i < (timeout_ms/100); i++)
+ if (si446x_mutex_take() == 0)
{
- if (si446x_wait_nirq())
+ for(i = 0; i < (timeout_ms/100); i++)
{
- res = (int)si446x_rx_packet(data, len);
+ if (si446x_wait_nirq())
+ {
+ res = (int)si446x_rx_packet(data, len);
+
+ sys_log_print_event_from_module(SYS_LOG_INFO, RADIO_MODULE_NAME, "Received ");
+ sys_log_print_uint(res);
+ sys_log_print_msg(" byte(s)...");
+ sys_log_new_line();
- si446x_clear_interrupts();
+ si446x_clear_interrupts();
- si446x_rx_init();
+ si446x_rx_init();
- break;
+ break;
+ }
+
+ vTaskDelay(pdMS_TO_TICKS(500));
}
- vTaskDelay(pdMS_TO_TICKS(500));
+ si446x_mutex_give();
+ }
+ else
+ {
+ sys_log_print_event_from_module(SYS_LOG_ERROR, RADIO_MODULE_NAME, "Couldn't get mutex control.");
+ sys_log_new_line();
}
return res;
@@ -120,7 +145,21 @@ int radio_available(void)
int radio_sleep(void)
{
- return (int)si446x_enter_standby_mode();
+ int err = -1;
+
+ if (si446x_mutex_take() == 0)
+ {
+ err = si446x_enter_standby_mode();
+
+ si446x_mutex_give();
+ }
+ else
+ {
+ sys_log_print_event_from_module(SYS_LOG_ERROR, RADIO_MODULE_NAME, "Couldn't get mutex control.");
+ sys_log_new_line();
+ }
+
+ return err;
}
int radio_get_temperature(radio_temp_t *temp)
diff --git a/firmware/devices/radio/radio.h b/firmware/devices/radio/radio.h
index 83ce7c58..8dceb308 100644
--- a/firmware/devices/radio/radio.h
+++ b/firmware/devices/radio/radio.h
@@ -24,10 +24,11 @@
* \brief Radio device definition.
*
* \author Gabriel Mariano Marcelino
- *
- * \version 0.1.23
- *
- * \date 2019/10/27
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \defgroup radio Radio
* \ingroup devices
@@ -83,7 +84,7 @@ int radio_send(uint8_t *data, uint16_t len);
int radio_recv(uint8_t *data, uint16_t len, uint32_t timeout_ms);
/**
- * \brief Verifies the number of availables bytes to receive.
+ * \brief Verifies if there are unread received bytes.
*
* \return The number of available bytes to receive (-1 on error).
*/
diff --git a/firmware/devices/radio/radio_data.h b/firmware/devices/radio/radio_data.h
index 182ccbb8..8131afd4 100644
--- a/firmware/devices/radio/radio_data.h
+++ b/firmware/devices/radio/radio_data.h
@@ -25,9 +25,9 @@
*
* \author Miguel Boing
*
- * \version 0.4.5
+ * \version 1.0.0
*
- * \date 2020/07/24
+ * \date 2024/09/09
*
* \defgroup radio_data Data
* \ingroup radio
@@ -55,7 +55,7 @@ typedef struct
uint32_t tx_packet_counter; /**< Number of total packets sent */
uint8_t rx_fifo_counter; /**< Packets received in queue */
uint8_t tx_fifo_counter; /**< Packets in queue to be sent */
- uint16_t *last_rx_packet_bytes; /**< Number of available bytes in the last packet received */
+ uint16_t last_rx_packet_bytes; /**< Number of available bytes in the last packet received */
} radio_data_t;
#endif /* RADIO_DATA_H_ */
diff --git a/firmware/devices/temp_sensor/temp_sensor.c b/firmware/devices/temp_sensor/temp_sensor.c
index 59ed9f11..efcc346b 100644
--- a/firmware/devices/temp_sensor/temp_sensor.c
+++ b/firmware/devices/temp_sensor/temp_sensor.c
@@ -24,10 +24,11 @@
* \brief Temperature sensor device implementation.
*
* \author Gabriel Mariano Marcelino
- *
- * \version 0.1.6
- *
- * \date 2020/03/17
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \addtogroup temp_sensor
* \{
@@ -95,9 +96,9 @@ uint16_t temp_sensor_raw_to_k(uint16_t raw)
{
int16_t temp_c = temp_sensor_raw_to_c(raw);
- if (temp_c < 273)
+ if (temp_c < -273)
{
- temp_c = 273;
+ temp_c = -273;
}
uint16_t res = temp_c + 273;
diff --git a/firmware/devices/temp_sensor/temp_sensor.h b/firmware/devices/temp_sensor/temp_sensor.h
index c72c3a56..db240d4a 100644
--- a/firmware/devices/temp_sensor/temp_sensor.h
+++ b/firmware/devices/temp_sensor/temp_sensor.h
@@ -24,10 +24,11 @@
* \brief Temperature sensor device definition.
*
* \author Gabriel Mariano Marcelino
- *
- * \version 0.1.3
- *
- * \date 2020/03/17
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
*
* \defgroup temp_sensor Temperature Sensor
* \ingroup devices
@@ -41,7 +42,7 @@
#define TEMP_SENSOR_MODULE_NAME "Temperature Sensor"
-#define TEMP_SENSOR_ADC_PORT ADC_PORT_5 /**< Temperature sensors ADC port (channel). */
+#define TEMP_SENSOR_ADC_PORT ADC_PORT_0 /**< Temperature sensors ADC port (channel). */
/**
* \brief Temperature sensor device initialization routine.
diff --git a/firmware/drivers/flash/flash.c b/firmware/drivers/flash/flash.c
index b57e4045..58c89308 100644
--- a/firmware/drivers/flash/flash.c
+++ b/firmware/drivers/flash/flash.c
@@ -1,7 +1,7 @@
/*
* flash.c
*
- * Copyright (C) 2021, SpaceLab.
+ * Copyright The TTC 2.0 Contributors.
*
* This file is part of TTC 2.0.
*
@@ -24,15 +24,17 @@
* \brief Flash driver implementation.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
*
- * \version 0.1.8
+ * \version 1.0.0
*
- * \date 2020/03/17
+ * \date 2024/09/09
*
* \addtogroup flash
* \{
*/
+
#include
#include "flash.h"
@@ -41,7 +43,7 @@ static long *current_flash_ptr;
int flash_init(void)
{
- return 0;
+ return flash_mutex_create();
}
void flash_write(uint8_t *data, uint16_t len)
@@ -133,6 +135,7 @@ uint32_t flash_read_long(uint32_t *addr)
void flash_erase(uint32_t *region)
{
uint32_t *erase_ptr = region;
+ uintptr_t seg = region;
if ((FCTL3 & LOCKA) > 0)
{
@@ -143,7 +146,7 @@ void flash_erase(uint32_t *region)
FCTL3 = FWKEY; /* Clear Lock bit */
}
- switch(*region)
+ switch(seg)
{
case FLASH_BANK_0_ADR: FCTL1 = FWKEY | MERAS; break;
case FLASH_BANK_1_ADR: FCTL1 = FWKEY | MERAS; break;
diff --git a/firmware/drivers/flash/flash.h b/firmware/drivers/flash/flash.h
index 84bf1f42..1d80dea3 100644
--- a/firmware/drivers/flash/flash.h
+++ b/firmware/drivers/flash/flash.h
@@ -1,7 +1,7 @@
/*
* flash.h
*
- * Copyright (C) 2021, SpaceLab.
+ * Copyright The TTC 2.0 Contributors.
*
* This file is part of TTC 2.0.
*
@@ -24,10 +24,11 @@
* \brief Flash driver definition.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
*
- * \version 0.0.5
+ * \version 1.0.0
*
- * \date 2020/03/17
+ * \date 2024/09/09
*
* \defgroup flash Flash
* \ingroup drivers
@@ -59,12 +60,19 @@
#define FLASH_MASS_ERASE 0X00FFFFFF
-/* Overflow flag message adress */
+/* Overflow flag message address */
#define FLASH_OVERFLOW_FLAG_ADDR 0x00026000
/* Last adress that can write a data(beyond this will enter the overflow) */
#define FLASH_LAST_WRITE_ADDR 0x00087FFF
+/* Mutex config. */
+#define FLASH_MUTEX_WAIT_TIME_MS 100
+
+/* Flash module name */
+#define FLASH_MODULE_NAME "Flash"
+
+
/**
* \brief Flash memory initialization.
*
@@ -132,6 +140,27 @@ uint32_t flash_read_long(uint32_t *addr);
*/
void flash_erase(uint32_t *region);
+/**
+ * \brief Creates a mutex to use the flash chip.
+ *
+ * \return The status/error code.
+ */
+int flash_mutex_create(void);
+
+/**
+ * \brief Holds the resource (flash chip).
+ *
+ * \return The status/error code.
+ */
+int flash_mutex_take(void);
+
+/**
+ * \brief Frees the resource (flash chip).
+ *
+ * \return The status/error code.
+ */
+int flash_mutex_give(void);
+
#endif /* FLASH_H_ */
/** \} End of flash group */
diff --git a/firmware/drivers/flash/flash_mutex.c b/firmware/drivers/flash/flash_mutex.c
new file mode 100644
index 00000000..85d98ca2
--- /dev/null
+++ b/firmware/drivers/flash/flash_mutex.c
@@ -0,0 +1,94 @@
+/*
+ * flash_mutex.c
+ *
+ * Copyright The TTC 2.0 Contributors.
+ *
+ * This file is part of TTC 2.0.
+ *
+ * TTC 2.0 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * TTC 2.0 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with TTC 2.0. If not, see .
+ *
+ */
+
+/**
+ * \brief Flash mutex functions implementation.
+ *
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
+ *
+ * \addtogroup flash
+ * \{
+ */
+
+#include
+
+#include
+#include
+
+#include "flash.h"
+#include
+
+static SemaphoreHandle_t flash_mutex = NULL;
+
+int flash_mutex_create(void)
+{
+ int err = 0;
+
+ flash_mutex = xSemaphoreCreateMutex();
+
+ if (flash_mutex == NULL)
+ {
+ sys_log_print_event_from_module(SYS_LOG_ERROR, FLASH_MODULE_NAME, "Error creating a mutex!");
+ sys_log_new_line();
+
+ err = -1;
+ }
+
+ return err;
+}
+
+int flash_mutex_take(void)
+{
+ int err = -1;
+
+ if (flash_mutex != NULL)
+ {
+ /* See if we can obtain the semaphore. If the semaphore is not */
+ /* available wait FLASH_MUTEX_WAIT_TIME_MS ms to see if it becomes free */
+ if (xSemaphoreTake(flash_mutex, pdMS_TO_TICKS(FLASH_MUTEX_WAIT_TIME_MS)) == pdTRUE)
+ {
+ err = 0;
+ }
+ }
+
+ return err;
+}
+
+int flash_mutex_give(void)
+{
+ int err = -1;
+
+ if (flash_mutex != NULL)
+ {
+ xSemaphoreGive(flash_mutex);
+
+ err = 0;
+ }
+
+ return err;
+}
+
+/**< \} End of flash group */
diff --git a/firmware/drivers/si446x/si446x.c b/firmware/drivers/si446x/si446x.c
index 5d986693..f6f12c3e 100644
--- a/firmware/drivers/si446x/si446x.c
+++ b/firmware/drivers/si446x/si446x.c
@@ -24,10 +24,11 @@
* \brief Si446x driver implementation.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
*
- * \version 0.2.10
+ * \version 1.0.0
*
- * \date 2017/06/01
+ * \date 2024/09/09
*
* \addtogroup si446x
* \{
@@ -36,7 +37,22 @@
#include
#include
-#include
+
+
+#if defined(RADIO_MODULE) && (RADIO_MODULE == 0)
+#include
+
+#elif defined(RADIO_MODULE) && (RADIO_MODULE == 1)
+#include
+
+#elif defined(SI446X_TEST)
+#include
+
+#else
+#error Define the target radio module on the configuration file (config/config.h)
+
+#endif /* CONFIG_DEV_RADIO_ENABLED */
+
#include
#include "si446x.h"
@@ -54,6 +70,9 @@ int si446x_init(void)
sys_log_new_line();
#endif /* CONFIG_DRIVERS_DEBUG_ENABLED */
+ /* Create si446x mutex */
+ si446x_mutex_create();
+
si446x_gpio_init();
si446x_spi_init();
@@ -108,12 +127,12 @@ void si446x_reg_config(void)
/* Set RF parameter like frequency, data rate, etc. */
si446x_set_config(SI446X_CONFIGURATION_DATA, sizeof(SI446X_CONFIGURATION_DATA));
+
uint8_t buf[2];
/* Frequency adjust (Tested manually) */
buf[0] = SI446X_XO_TUNE_REG_VALUE;
si446x_set_properties(SI446X_PROPERTY_GLOBAL_XO_TUNE, buf, 1);
-
/* TX/RX shares 128 bytes FIFO */
buf[0] = 0x10;
si446x_set_properties(SI446X_PROPERTY_GLOBAL_CONFIG, buf, 1);
@@ -280,7 +299,7 @@ uint8_t si446x_rx_packet(uint8_t *rx_buf, uint8_t read_len)
bool si446x_rx_init(void)
{
- uint8_t length = 50;
+ uint8_t length = 0x50;
si446x_set_properties(SI446X_PROPERTY_PKT_FIELD_2_LENGTH_7_0, &length, 1); /* Reload RX FIFO size */
si446x_fifo_reset(); /* Clear FIFO */
@@ -464,9 +483,10 @@ void si446x_set_config(const uint8_t *parameters, uint16_t para_len)
cmd_len = parameters[pos++] - 1; /* Get command len */
cmd = parameters[pos++]; /* Get command */
memcpy(buffer, parameters + pos, cmd_len); /* Get parameters */
-
+ si446x_delay_ms(10);
si446x_set_cmd(cmd, buffer, cmd_len);
pos += cmd_len;
+
}
}
diff --git a/firmware/drivers/si446x/si446x.h b/firmware/drivers/si446x/si446x.h
index a5c987a8..9689e644 100644
--- a/firmware/drivers/si446x/si446x.h
+++ b/firmware/drivers/si446x/si446x.h
@@ -24,10 +24,11 @@
* \brief Si446x driver definition.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
*
- * \version 0.4.3
+ * \version 1.0.0
*
- * \date 2017/06/01
+ * \date 2024/09/09
*
* \defgroup si446x Si446x
* \{
@@ -39,6 +40,9 @@
#include
#include
+/* Mutex config. */
+#define SI446X_MUTEX_WAIT_TIME_MS 100
+
/**
* \brief Si446x modes.
*/
diff --git a/firmware/drivers/si446x/si446x_config.h b/firmware/drivers/si446x/si446x_config.h
index 4e7933d9..a986f28a 100644
--- a/firmware/drivers/si446x/si446x_config.h
+++ b/firmware/drivers/si446x/si446x_config.h
@@ -1,34 +1,35 @@
/*
* si446x_config.h
- *
+ *
* Copyright The TTC 2.0 Contributors.
- *
+ *
* This file is part of TTC 2.0.
- *
+ *
* TTC 2.0 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* TTC 2.0 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with TTC 2.0. If not, see .
- *
+ *
*/
/**
* \brief Si446x configuration.
- *
+ *
* \author Gabriel Mariano Marcelino
- *
- * \version 0.1.23
- *
- * \date 2017/06/16
- *
+ * \author Miguel Boing
+ *
+ * \version 1.0.0
+ *
+ * \date 2024/09/09
+ *
* \addtogroup si446x
* \{
*/
diff --git a/firmware/drivers/si446x/si446x_mutex.c b/firmware/drivers/si446x/si446x_mutex.c
index b5d7363e..ed61c915 100644
--- a/firmware/drivers/si446x/si446x_mutex.c
+++ b/firmware/drivers/si446x/si446x_mutex.c
@@ -24,50 +24,74 @@
* \brief Si446x mutex functions implementation.
*
* \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
*
- * \version 0.4.5
+ * \version 1.0.0
*
- * \date 2023/04/13
+ * \date 2024/09/09
*
* \addtogroup si446x
* \{
*/
+#include
+
#include
#include
+#include
+
#include "si446x.h"
#include "si446x_config.h"
-static SemaphoreHandle_t si446x_semaphore = NULL;
-
-#define SI446X_MUTEX_WAIT_TIME_MS 100;
+static SemaphoreHandle_t si446x_mutex = NULL;
int si446x_mutex_create(void)
{
- return 0;
+ int err = 0;
+
+ si446x_mutex = xSemaphoreCreateMutex();
+
+ if (si446x_mutex == NULL)
+ {
+ sys_log_print_event_from_module(SYS_LOG_ERROR, SI446X_MODULE_NAME, "Error creating a mutex!");
+ sys_log_new_line();
+
+ err = -1;
+ }
+
+ return err;
}
int si446x_mutex_take(void)
{
int err = -1;
- //if (si446x_semaphore != NULL)
- //{
+ if (si446x_mutex != NULL)
+ {
/* See if we can obtain the semaphore. If the semaphore is not */
- /* available wait SYS_LOG_MUTEX_WAIT_TIME_MS ms to see if it becomes free */
- // if (xSemaphoreTake(si446x_semaphore, pdMS_TO_TICKS(SI446X_MUTEX_WAIT_TIME_MS)) == pdTRUE)
- //{
- // err = 0;
- //}
- //}
+ /* available wait SI446X_MUTEX_WAIT_TIME_MS ms to see if it becomes free */
+ if (xSemaphoreTake(si446x_mutex, pdMS_TO_TICKS(SI446X_MUTEX_WAIT_TIME_MS)) == pdTRUE)
+ {
+ err = 0;
+ }
+ }
return err;
}
int si446x_mutex_give(void)
{
- return 0;
+ int err = -1;
+
+ if (si446x_mutex != NULL)
+ {
+ xSemaphoreGive(si446x_mutex);
+
+ err = 0;
+ }
+
+ return err;
}
/**< \} End of si446x group */
diff --git a/firmware/drivers/spi_slave/spi_slave.c b/firmware/drivers/spi_slave/spi_slave.c
index 4bdfcc08..3539b86a 100644
--- a/firmware/drivers/spi_slave/spi_slave.c
+++ b/firmware/drivers/spi_slave/spi_slave.c
@@ -25,9 +25,9 @@
*
* \author Miguel Boing
*
- * \version 0.4.5
+ * \version 1.0.0
*
- * \date 2022/05/21
+ * \date 2024/09/09
*
* \addtogroup spi_slave
* \{
@@ -81,11 +81,11 @@ static int spi_read_isr_rx_buffer(spi_port_t port, uint8_t *data, uint16_t len);
static int spi_slave_setup_gpio(spi_port_t port);
-static uint8_t spi_slave_dma_tx_data[228] = {0};
-static uint8_t spi_slave_dma_rx_data[228] = {0};
+#define DMA_TX_TRANSFER_SIZE 7
+#define DMA_RX_TRANSFER_SIZE 7
-static uint16_t spi_slave_dma_tx_position;
-static uint16_t spi_slave_dma_rx_position;
+static uint8_t spi_slave_dma_tx_data[230U] = {0};
+static uint8_t spi_slave_dma_rx_data[230U] = {0};
int spi_slave_init(spi_port_t port, spi_config_t config)
{
@@ -100,7 +100,7 @@ int spi_slave_init(spi_port_t port, spi_config_t config)
static DMA_initParam spi_slave_dma_param_tx = {
.channelSelect = DMA_CHANNEL_0,
.transferModeSelect = DMA_TRANSFER_REPEATED_SINGLE,
- .transferSize = 228,
+ .transferSize = DMA_TX_TRANSFER_SIZE,
.triggerSourceSelect = DMA_TRIGGERSOURCE_13,
.transferUnitSelect = DMA_SIZE_SRCBYTE_DSTBYTE,
.triggerTypeSelect = DMA_TRIGGER_HIGH,
@@ -109,7 +109,7 @@ int spi_slave_init(spi_port_t port, spi_config_t config)
static DMA_initParam spi_slave_dma_param_rx = {
.channelSelect = DMA_CHANNEL_1,
.transferModeSelect = DMA_TRANSFER_REPEATED_SINGLE,
- .transferSize = 228,
+ .transferSize = DMA_RX_TRANSFER_SIZE,
.triggerSourceSelect = DMA_TRIGGERSOURCE_12,
.transferUnitSelect = DMA_SIZE_SRCBYTE_DSTBYTE,
.triggerTypeSelect = DMA_TRIGGER_HIGH,
@@ -309,11 +309,13 @@ int spi_slave_init(spi_port_t port, spi_config_t config)
DMA_enableTransfers(DMA_CHANNEL_0);
- spi_slave_dma_rx_position = 0U;
-
- for(i = 0U; i < 228U; i++)
+ for(i = 0U; i < (uint8_t) DMA_RX_TRANSFER_SIZE; i++)
{
spi_slave_dma_rx_data[i] = 0xFFU;
+ }
+
+ for(i = 0U; i < (uint8_t) DMA_TX_TRANSFER_SIZE; i++)
+ {
spi_slave_dma_tx_data[i] = 0xFFU;
}
@@ -325,9 +327,6 @@ int spi_slave_init(spi_port_t port, spi_config_t config)
spi_slave_dma_tx_data[5] = 0x00U;
spi_slave_dma_tx_data[6] = 0x00U;
- /* Next command preamble */
- spi_slave_dma_tx_data[7] = 0x7EU;
-
DMA_init(&spi_slave_dma_param_rx);
DMA_setSrcAddress(DMA_CHANNEL_1, USCI_A_SPI_getReceiveBufferAddressForDMA(base_address), DMA_DIRECTION_UNCHANGED);
@@ -340,8 +339,6 @@ int spi_slave_init(spi_port_t port, spi_config_t config)
DMA_enableTransfers(DMA_CHANNEL_1);
- spi_slave_dma_tx_position = 8U;
-
__bis_SR_register(LPM4_bits + GIE);
if (err == 0)
@@ -371,56 +368,41 @@ void spi_slave_dma_write(uint8_t *data, uint16_t len)
for(i = 0U; i < len; i++)
{
- spi_slave_dma_tx_data[spi_slave_dma_tx_position] = data[i];
-
- spi_slave_dma_tx_position++;
-
- if (spi_slave_dma_tx_position > 227U) /* Reset position after the end of the buffer */
- {
- spi_slave_dma_tx_position = 0U;
- }
+ spi_slave_dma_tx_data[i] = data[i];
}
+}
- spi_slave_dma_tx_data[spi_slave_dma_tx_position] = 0x7EU;
-
- spi_slave_dma_tx_position++;
+void spi_slave_dma_read(uint8_t *data, uint16_t len)
+{
+ uint16_t i = 0U;
- if (spi_slave_dma_tx_position > 227U) /* Reset position after the end of the buffer */
+ for(i = 0U; i < len; i++)
{
- spi_slave_dma_tx_position = 0U;
+ data[i] = spi_slave_dma_rx_data[i];
+ spi_slave_dma_rx_data[i] = 0xFFU; /* Clear after read */
}
}
-void spi_slave_dma_read(uint8_t *data, uint16_t len)
+void spi_slave_dma_change_transfer_size(uint16_t transfer_size)
{
- uint16_t i = 0U;
+ DMA_disableTransfers(DMA_CHANNEL_0);
+ DMA_disableTransfers(DMA_CHANNEL_1);
- if ((spi_slave_dma_rx_data[spi_slave_dma_rx_position] != 0xFFU))
- {
- for(i = 0U; i < len; i++)
- {
- data[i] = spi_slave_dma_rx_data[spi_slave_dma_rx_position];
+ USCI_A_SPI_disable(USCI_A2_BASE);
+ USCI_A_SPI_enable(USCI_A2_BASE);
- spi_slave_dma_rx_data[spi_slave_dma_rx_position] = 0xFFU; /* Clear after read */
+ DMA_setSrcAddress(DMA_CHANNEL_0, (uint32_t)(uintptr_t)spi_slave_dma_tx_data, DMA_DIRECTION_INCREMENT); // cppcheck-suppress misra-c2012-11.4
+ DMA_setDstAddress(DMA_CHANNEL_1, (uint32_t)(uintptr_t)spi_slave_dma_rx_data, DMA_DIRECTION_INCREMENT); // cppcheck-suppress misra-c2012-11.4
- spi_slave_dma_rx_position++;
+ DMA_setTransferSize(DMA_CHANNEL_0, transfer_size);
+ DMA_setTransferSize(DMA_CHANNEL_1, transfer_size);
- if (spi_slave_dma_rx_position > 227U)
- {
- spi_slave_dma_rx_position = 0U; /* Reset position after the end of the buffer */
- }
- }
- }
+ DMA_enableTransfers(DMA_CHANNEL_0);
+ DMA_enableTransfers(DMA_CHANNEL_1);
- else
- {
- for (i=0U; i < len; i++)
- {
- data[i] = 0xFFU;
- }
- }
}
+
static int spi_slave_setup_gpio(spi_port_t port)
{
int err = 0;
diff --git a/firmware/drivers/spi_slave/spi_slave.h b/firmware/drivers/spi_slave/spi_slave.h
index cf84111e..98296b34 100644
--- a/firmware/drivers/spi_slave/spi_slave.h
+++ b/firmware/drivers/spi_slave/spi_slave.h
@@ -25,9 +25,9 @@
*
* \author Miguel Boing
*
- * \version 0.4.5
+ * \version 1.0.0
*
- * \date 2022/05/21
+ * \date 2024/09/09
*
* \defgroup spi_slave SPI_SLAVE
* \ingroup drivers
@@ -84,6 +84,8 @@ void spi_slave_dma_write(uint8_t *data, uint16_t len);
*/
void spi_slave_dma_read(uint8_t *data, uint16_t len);
+void spi_slave_dma_change_transfer_size(uint16_t transfer_size);
+
/**
* \brief Enables SPI Slave port interruption.
*
diff --git a/firmware/lnk_msp430f5659.cmd b/firmware/lnk_msp430f5659.cmd
new file mode 100644
index 00000000..d9834253
--- /dev/null
+++ b/firmware/lnk_msp430f5659.cmd
@@ -0,0 +1,252 @@
+/* ============================================================================ */
+/* Copyright (c) 2020, Texas Instruments Incorporated */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions */
+/* are met: */
+/* */
+/* * Redistributions of source code must retain the above copyright */
+/* notice, this list of conditions and the following disclaimer. */
+/* */
+/* * Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* * Neither the name of Texas Instruments Incorporated nor the names of */
+/* its contributors may be used to endorse or promote products derived */
+/* from this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" */
+/* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, */
+/* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
+/* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, */
+/* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, */
+/* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; */
+/* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, */
+/* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/* ============================================================================ */
+
+/******************************************************************************/
+/* lnk_msp430f5659.cmd - LINKER COMMAND FILE FOR LINKING MSP430F5659 PROGRAMS */
+/* */
+/* Usage: lnk430 -o -m