Compare commits
107 Commits
@ -0,0 +1,272 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
####################################################################################################
|
||||
# CMAKE Features
|
||||
####################################################################################################
|
||||
# do this instead of declaring languages in the beginning this WILL prevent loop errors.
|
||||
project(${CSL_USED} ASM C CXX)
|
||||
# Defining the executables name
|
||||
set(EXECUTABLE ${PROJECT_NAME})
|
||||
|
||||
####################################################################################################
|
||||
# NON-VITAL OPTION FOR COMPILATION
|
||||
####################################################################################################
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE OFF) # Should CMake print everythign ?
|
||||
|
||||
set(OUTPUT_DOXYGEN FALSE) # Should CMake generate Doxygen output ?
|
||||
set(DOXYGEN_OUTPUT_DIR ${CMAKE_SOURCE_DIR}/env/doc)
|
||||
|
||||
# TODO: discuss on where doxygen should place the output
|
||||
# -> in env/doc
|
||||
# -> in ked_build outside of the ked environment (prefered, as it includes also the users
|
||||
# project documentation
|
||||
# idea -> creakte an override option in the projectConfig.cmake file to be able to define
|
||||
# where and waht.
|
||||
set(PL "c") # Used programming language, we could maybe do a check.
|
||||
|
||||
####################################################################################################
|
||||
# PASSED VARIABLE WHEN CALLING run.sh
|
||||
####################################################################################################
|
||||
# CSL_USED passed by run.sh and is the quivalent of the ic name
|
||||
# PROJECT_DIR Passed by run.sh and is the defined place where the project is. run.sh should be in
|
||||
# the future capable of definin project paht.
|
||||
|
||||
####################################################################################################
|
||||
# Setting the used directory locations
|
||||
####################################################################################################
|
||||
# Location of the project : It is defaulted to one Higher than the KED Directory :TODO: Shall we let
|
||||
set(PROJECT_CONFIG_FILE ${PROJECT_DIR}/projectDefinitions.cmake)
|
||||
|
||||
# Location of the cmkae core funtionalities / funtions / definitions
|
||||
set(CMAKE_CORE_DIR ${CMAKE_SOURCE_DIR}/env/cmake_core)
|
||||
set(COMPILER_DEFS ${CMAKE_CORE_DIR}/compiler.cmake)
|
||||
|
||||
# Location of CSL, CSL_USED is passed as an argument to CMake from run.sh
|
||||
# -> "Specific to each CSL"
|
||||
set(CSL_DIR ${CMAKE_SOURCE_DIR}/csl/${CSL_USED})
|
||||
set(CSL_CONFIG_FILE ${CSL_DIR}/config.cmake)
|
||||
|
||||
# To Put one layer down so that CMSIS is defined by the CSL it's core specific stuff
|
||||
set(CSL_SOURCES_DIR ${CSL_DIR}/implementation)
|
||||
set(CSL_HEADERS_DIR ${CSL_DIR}/CMSIS/Include ${CSL_DIR}/HardwareDescription)
|
||||
set(CSL_STARTUP_DIR ${CSL_DIR}/startup)
|
||||
####################################################################################
|
||||
|
||||
# Directiry fot the drivers -> "Common to all CSL"
|
||||
set(DRIVERS_DIR ${CMAKE_SOURCE_DIR}/drivers)
|
||||
set(DRIVERS_HEADERS_DIR) #Declared empty because it will be filled automaticaly afterwards
|
||||
|
||||
# Directory fot the peripherals -> "Common to all CSL"
|
||||
set(PERIPHERALS_DIR ${CMAKE_SOURCE_DIR}/peripherals)
|
||||
set(PERIPHERALS_HEADERS_DIR)#Declared empty because it will be filled automaticaly afterwards
|
||||
set(PERIPHERAL_LIBS)#Declared empty because it will be filled automaticaly afterwards
|
||||
|
||||
# Directory for the libraries -> "Common to all CSL"
|
||||
set(LIBRARIES_DIR ${CMAKE_SOURCE_DIR}/libraries)
|
||||
set(LIBRARIES_HEADERS_DIR)#Declared empty because it will be filled automaticaly afterwards
|
||||
set(LIBRARIES_LIBS)#Declared empty because it will be filled automaticaly afterwards
|
||||
|
||||
# Directory for the SYSTEM -> "Common to all CSL"
|
||||
set(SYSTEM_DIR ${CMAKE_SOURCE_DIR}/system)
|
||||
set(SYSTEM_HEADERS_DIR)#Declared empty because it will be filled automaticaly afterwards
|
||||
set(SYSTEM_LIBS)#Declared empty because it will be filled automaticaly afterwards
|
||||
|
||||
####################################################################################################
|
||||
# INCLUDES ####################################################################################################
|
||||
# Adding human readable color references for cmake
|
||||
include(${CMAKE_CORE_DIR}/colors.cmake)
|
||||
|
||||
# All the library and submodule funtions and definitions are written here
|
||||
include(${CMAKE_CORE_DIR}/cmakeCore.cmake)
|
||||
|
||||
# For Detailed error messages.
|
||||
include(${CMAKE_CORE_DIR}/errorHandler.cmake)
|
||||
|
||||
# For Doxygen document generatio
|
||||
include(${CMAKE_CORE_DIR}/doxygen.cmake)
|
||||
|
||||
# All the library and submodule funtions and definitions are written here
|
||||
include(${CMAKE_CORE_DIR}/cmakeProject.cmake)
|
||||
|
||||
# Include the project definition defined by the end user implementiogn KED as a submodule
|
||||
include(${PROJECT_CONFIG_FILE})
|
||||
|
||||
# Here is the include fopr the awailable peripheral headers and standart libraries.
|
||||
include(${PERIPHERALS_DIR}/CMakeLists.txt)
|
||||
|
||||
# Here is the include fopr the awailable drivers headers and standart libraries.
|
||||
include(${DRIVERS_DIR}/CMakeLists.txt)
|
||||
|
||||
# Here is the include fopr the awailable libraries headers and standart libraries.
|
||||
include(${LIBRARIES_DIR}/CMakeLists.txt)
|
||||
|
||||
# Here is the include fopr the awailable system headers and standart libraries.
|
||||
include(${SYSTEM_DIR}/CMakeLists.txt)
|
||||
|
||||
# Include the config fiel where the compilers to use ar defined
|
||||
include(${COMPILER_DEFS})
|
||||
|
||||
# Confugration file of the csl, there you will wind the starup code handling, compiler/linker
|
||||
# options, flags and definitions
|
||||
include(${CSL_CONFIG_FILE})
|
||||
|
||||
####################################################################################################
|
||||
# HEADERS : ALL Header Definitions and calls MUST be made here to be able to propagate them through
|
||||
# all the modules
|
||||
####################################################################################################
|
||||
message("${BoldBlue}")
|
||||
message("+-------------------------------+")
|
||||
message("Adding Header Directories")
|
||||
message("+-------------------------------+")
|
||||
message("|-->For System")
|
||||
createHeaderDirList("${SYSTEM_DIR}" "${SYSTEM_LIST}" "SYSTEM_HEADERS_DIR")
|
||||
message("${BoldBlue}|-->For Peripherals")
|
||||
createHeaderDirList("${PERIPHERALS_DIR}" "${PERIPHERALS_LIST}" "PERIPHERALS_HEADERS_DIR")
|
||||
message("${BoldBlue}|-->For Drivers")
|
||||
createHeaderDirList("${DRIVERS_DIR}" "${DRIVERS_LIST}" "DRIVERS_HEADERS_DIR")
|
||||
message("${BoldBlue}|-->For Libraries")
|
||||
createHeaderDirList("${LIBRARIES_DIR}" "${LIBRARIES_LIST}" "LIBRARIES_HEADERS_DIR")
|
||||
message("${BoldBlue}|-->For Project")
|
||||
createHeaderDirListProject("${PROJECT_ADDITIONAL_DIRS}" "PROJECT_HEADERS_DIR")
|
||||
message("${BoldBlue}+-------------------------------+${ColourReset}")
|
||||
|
||||
#Stick all the herade direcotries together for ease of use further down
|
||||
set (COMMON_HEADERS ${CSL_HEADERS_DIR}
|
||||
${SYSTEM_HEADERS_DIR}
|
||||
${PERIPHERALS_HEADERS_DIR}
|
||||
${DRIVERS_HEADERS_DIR}
|
||||
${LIBRARIES_HEADERS_DIR}
|
||||
${PROJECT_HEADERS_DIR})
|
||||
|
||||
####################################################################################################
|
||||
# Making Modules
|
||||
####################################################################################################
|
||||
message("${BoldBlue}")
|
||||
message("+-------------------------------+")
|
||||
message("Making Submolues")
|
||||
message("+-------------------------------+")
|
||||
message("|-->For System")
|
||||
makeSubmodules("${SYSTEM_DIR}" "${SYSTEM_LIST}" "SYSTEM_LIBS")
|
||||
message("${BoldBlue}|-->For Peripherals")
|
||||
makeSubmodules("${PERIPHERALS_DIR}" "${PERIPHERALS_LIST}" "PERIPHERAL_LIBS")
|
||||
message("${BoldBlue}|-->For Drivers")
|
||||
makeSubmodules("${DRIVERS_DIR}" "${DRIVERS_LIST}" "DRIVER_LIBS")
|
||||
message("${BoldBlue}|-->For Libraries")
|
||||
makeSubmodules("${LIBRARIES_DIR}" "${LIBRARIES_LIST}" "LIBRARIES_LIBS")
|
||||
message("${BoldBlue}|-->For Project")
|
||||
makeSubmodulesProject("${PROJECT_ADDITIONAL_DIRS}" "${PROJECT_TO_COMPILE_LIST}" "PROJECT_LIBS")
|
||||
message("${BoldBlue}+-------------------------------+${ColourReset}")
|
||||
|
||||
# Stick All the libraries together, only for code redability futher down.
|
||||
set(GENERATED_LIBRARIES ${PROJECT_LIBS}
|
||||
${STARTUP_UCODE}
|
||||
${SYSTEM_LIBS}
|
||||
${PERIPHERAL_LIBS}
|
||||
${DRIVER_LIBS}
|
||||
${LIBRARIES_LIBS})
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Overview
|
||||
####################################################################################################
|
||||
message("${BoldBlue}")
|
||||
message("+-------------------------------+")
|
||||
message("Project Info")
|
||||
message("+-------------------------------+")
|
||||
message(" |--> Executable Name:${BoldCyan} ${EXECUTABLE} ${BoldBlue}")
|
||||
message(" |--> Startup uCode :${BoldCyan} ${STARTUP_CODE} ${BoldBlue}")
|
||||
message(" |--> Linker :${BoldCyan} ${LINKER} ${BoldBlue}")
|
||||
message(" |--> Project Dir :${BoldCyan} ${PROJECT_DIR} ${BoldBlue}")
|
||||
message(" |--> Project Config :${BoldCyan} ${PROJECT_CONFIG_FILE} ${BoldBlue}")
|
||||
message(" |--> CSL Dir :${BoldCyan} ${CSL_DIR} ${BoldBlue}")
|
||||
message(" |--> CSL Config :${BoldCyan} ${CSL_CONFIG_FILE} ${BoldBlue}")
|
||||
message(" |--> Compiler Config:${BoldCyan} ${COMPILER_DEFS} ${BoldBlue}")
|
||||
|
||||
message("${BoldBlue}")
|
||||
message("+-------------------------------+")
|
||||
message("Compiling Info")
|
||||
message("+-------------------------------+")
|
||||
message("|--> Main Compile Definitions:")
|
||||
printList("${BoldCyan} | " "${MAIN_DEFS}")
|
||||
message("${BoldBlue}|--> Main Compile Flags:")
|
||||
printList("${BoldCyan} | " "${MAIN_FLAGS}")
|
||||
message("${BoldBlue}|--> Linker Flags:")
|
||||
printList("${BoldCyan} | " "${LINKER_FLAGS}")
|
||||
message("${BoldBlue}|--> Periferals which will be implemented:")
|
||||
printList("${BoldCyan} |-> " "${PERIPHERALS_LIST}")
|
||||
message("${BoldBlue}|--> Drivers which will be implemented:")
|
||||
printList("${BoldCyan} |-> " "${DRIVERS_LIST}")
|
||||
message("${BoldBlue}|--> Project sources to be implemented:")
|
||||
printList("${BoldCyan} |-> " "${PROJECT_TO_COMPILE_LIST}")
|
||||
message("${BoldBlue}|--> Generated Library Submodules ${Red}!!!The Order Matters!!!${ColourReset}${BoldCyan}")
|
||||
printList("${BoldCyan} |-> " "${GENERATED_LIBRARIES}")
|
||||
message("${BoldBlue}+-------------------------------+${ColourReset}")
|
||||
|
||||
####################################################################################################
|
||||
# EXECUTABLE
|
||||
####################################################################################################
|
||||
add_executable(${EXECUTABLE} ${PROJECT_DIR}/main.${PL})
|
||||
target_compile_options(${EXECUTABLE} PRIVATE ${MAIN_FLAGS})
|
||||
target_compile_definitions(${EXECUTABLE} PRIVATE ${MAIN_DEFS})
|
||||
target_include_directories(${EXECUTABLE} PUBLIC ${COMMON_HEADERS})
|
||||
|
||||
####################################################################################################
|
||||
# LINKING EXECUTEABLE
|
||||
####################################################################################################
|
||||
message("${BoldGreen}")
|
||||
message("+-------------------------------+")
|
||||
message("Linker & Compiler Info")
|
||||
message("+-------------------------------+")
|
||||
|
||||
if(IS_NO_SYS)
|
||||
target_link_libraries(${EXECUTABLE} ${GENERATED_LIBRARIES})
|
||||
target_link_options(${EXECUTABLE} PRIVATE ${LINKER_FLAGS})
|
||||
else ()
|
||||
target_link_libraries(${EXECUTABLE} ${GENERATED_LIBRARIES})
|
||||
endif()
|
||||
|
||||
message(" |-> LINKER : ${LINKER}")
|
||||
message(" |-> C_COMPILER : ${CMAKE_C_COMPILER}")
|
||||
message(" |-> CXX_COMPILER: ${CMAKE_CXX_COMPILER}")
|
||||
message(" |-> ASM_COMPILER: ${CMAKE_ASM_COMPILER}")
|
||||
message(" |-> OBJCOPY : ${CMAKE_OBJCOPY}")
|
||||
message(" |-> SIZE : ${CMAKE_SIZE}")
|
||||
|
||||
# AS we provide our own linker nad not using the one from the curren OS (system)
|
||||
message(" |-> LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}")
|
||||
message("+-------------------------------+")
|
||||
message("${ColourReset}")
|
||||
|
||||
####################################################################################################
|
||||
# CUSTOM COMMANDS
|
||||
####################################################################################################
|
||||
|
||||
if(NEED_OBJCOPY)
|
||||
add_custom_command(TARGET ${EXECUTABLE}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE} ${PROJECT_NAME}.hex
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE} ${PROJECT_NAME}.bin)
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET ${EXECUTABLE}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_SIZE} ${EXECUTABLE})
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Documentation generation
|
||||
####################################################################################################
|
||||
generateDoxygen()
|
||||
|
||||
####################################################################################################
|
||||
#CUSTOM Comments from dev.
|
||||
####################################################################################################
|
||||
# Link For header dependency : https://stackoverflow.com/questions/11216408/cmake-dependencies-
|
||||
# headers-between-apps-libraries-in-same-project
|
||||
# This is one possible trick to handle the assenbly compiling.
|
||||
# We can't use arm-non-eabi-as because it can onaly hande macros.
|
||||
# So this bizzare Variable makes shure that whne the asembly compiling is called the -x assembler-
|
||||
# with-cpp flag is passed
|
||||
# target_compile_options(${EXECUTABLE} PRIVATE
|
||||
# $<$<COMPILE_LANGUAGE:ASM>:-x assembler-with-cpp ${ASM_FLAGS}>)
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,51 @@
|
||||
/**
|
||||
**************************************************************************************************
|
||||
* @file hardwareDescription.h
|
||||
* @author Kerem Yollu & Edwin Koch
|
||||
* @date 19.12.2021
|
||||
* @version 1.0
|
||||
**************************************************************************************************
|
||||
* @brief This file contains all hardware specific definitions for STM32F042K6
|
||||
*
|
||||
* **Detailed Description :**
|
||||
* This Header file contains all the registers and their bit manipulation options.
|
||||
* All the extra Tables created here are to somplifly the main codes readability
|
||||
*
|
||||
* @todo
|
||||
* - 19.12.2021 : implement until it runs :)
|
||||
**************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _hardwareDescription_H_
|
||||
#define _hardwareDescription_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stm32f042x6.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define PACKAGE_LQFP32 1
|
||||
|
||||
#define MAX_I2S_CHANNEL_COUNT 2
|
||||
#define MAX_CAN_CHANNEL_COUNT 1
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* Enum for awailable clok sources RM Page: 95
|
||||
* */
|
||||
typedef enum {
|
||||
CLK_HSI, /*!< High speed internal */
|
||||
CLK_HSE, /*!< High speed external */
|
||||
CLK_LSI, /*!< Low speed internal */
|
||||
CLK_LSE /*!< Low speed External */
|
||||
}clkSources_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _hardwareDescription_H_
|
@ -0,0 +1,56 @@
|
||||
/**
|
||||
**************************************************************************************************
|
||||
* @file hwd_i2c.h
|
||||
* @author Kerem Yollu & Edwin Koch
|
||||
* @date 26.02.2023
|
||||
* @version 1.0
|
||||
**************************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* **Detailed Description :**
|
||||
*
|
||||
**************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _HWD_I2C_H_
|
||||
#define _HWD_I2C_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hardwareDescription.h"
|
||||
|
||||
#define MAX_I2C_CHANNEL_COUNT 1
|
||||
|
||||
/*! Awailable I2C Channels Hadware dependent Register independent */
|
||||
typedef enum{
|
||||
I2C_CH_1
|
||||
}i2cCh_t;
|
||||
|
||||
|
||||
/*! I2C Channel Base adress Hadware dependent Register dependent*/
|
||||
static const uint32_t i2cBase_Addr_List[MAX_I2C_CHANNEL_COUNT] = {
|
||||
I2C1_BASE
|
||||
};
|
||||
|
||||
/*! RCC Bus number index list connected to the I2C */
|
||||
static const uint8_t i2cBus_No[MAX_I2C_CHANNEL_COUNT] = {
|
||||
1 /*!< I2C1 is connected to bus 1 */
|
||||
};
|
||||
|
||||
/*! RCC I2C clock enable bit position for the given register*/
|
||||
static const uint8_t i2cBus_En_bitPos[MAX_I2C_CHANNEL_COUNT] = {
|
||||
RCC_APB1ENR_I2C1EN_Pos
|
||||
};
|
||||
|
||||
/*! RCC I2C reset bit position for the given register*/
|
||||
static const uint8_t i2cBus_Rst_bitPos[MAX_I2C_CHANNEL_COUNT] = {
|
||||
RCC_APB1RSTR_I2C1RST_Pos
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _HWD_I2C_H_
|
@ -0,0 +1,144 @@
|
||||
/**
|
||||
**************************************************************************************************
|
||||
* @file hwd_interrupt.h
|
||||
* @author Kerem Yollu & Edwin Koch
|
||||
* @date 26.02.2023
|
||||
* @version 1.0
|
||||
**************************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* **Detailed Description :**
|
||||
*
|
||||
**************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _HWD_INTERRUPT_H_
|
||||
#define _HWD_INTERRUPT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "interrupt.h"
|
||||
#include "hardwareDescription.h"
|
||||
|
||||
/*! interrupt types. These act as indexes for the */
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
PINX0_RISING_EDGE,
|
||||
PINX0_FALLING_EDGE,
|
||||
PINX0_BOTH_EDGE,
|
||||
PINX1_RISING_EDGE,
|
||||
PINX1_FALLING_EDGE,
|
||||
PINX1_BOTH_EDGE,
|
||||
PINX2_RISING_EDGE,
|
||||
PINX2_FALLING_EDGE,
|
||||
PINX2_BOTH_EDGE,
|
||||
PINX3_RISING_EDGE,
|
||||
PINX3_FALLING_EDGE,
|
||||
PINX3_BOTH_EDGE,
|
||||
PINX4_RISING_EDGE,
|
||||
PINX4_FALLING_EDGE,
|
||||
PINX4_BOTH_EDGE,
|
||||
PINX5_RISING_EDGE,
|
||||
PINX5_FALLING_EDGE,
|
||||
PINX5_BOTH_EDGE,
|
||||
PINX6_RISING_EDGE,
|
||||
PINX6_FALLING_EDGE,
|
||||
PINX6_BOTH_EDGE,
|
||||
PINX7_RISING_EDGE,
|
||||
PINX7_FALLING_EDGE,
|
||||
PINX7_BOTH_EDGE,
|
||||
PINX8_RISING_EDGE,
|
||||
PINX8_FALLING_EDGE,
|
||||
PINX8_BOTH_EDGE,
|
||||
PINX9_RISING_EDGE,
|
||||
PINX9_FALLING_EDGE,
|
||||
PINX9_BOTH_EDGE,
|
||||
PINX10_RISING_EDGE,
|
||||
PINX10_FALLING_EDGE,
|
||||
PINX10_BOTH_EDGE,
|
||||
PINX11_RISING_EDGE,
|
||||
PINX11_FALLING_EDGE,
|
||||
PINX11_BOTH_EDGE,
|
||||
PINX12_RISING_EDGE,
|
||||
PINX12_FALLING_EDGE,
|
||||
PINX12_BOTH_EDGE,
|
||||
PINX13_RISING_EDGE,
|
||||
PINX13_FALLING_EDGE,
|
||||
PINX13_BOTH_EDGE,
|
||||
PINX14_RISING_EDGE,
|
||||
PINX14_FALLING_EDGE,
|
||||
PINX14_BOTH_EDGE,
|
||||
PINX15_RISING_EDGE,
|
||||
PINX15_FALLING_EDGE,
|
||||
PINX15_BOTH_EDGE,
|
||||
TIM1_BREAK,
|
||||
TIM1_UPDATE,
|
||||
TIM1_TRIGGER,
|
||||
TIM1_COMMUNICATION,
|
||||
TIM1_COUNTERCOMPARE_1,
|
||||
TIM1_COUNTERCOMPARE_2,
|
||||
TIM1_COUNTERCOMPARE_3,
|
||||
TIM1_COUNTERCOMPARE_4,
|
||||
TIM2_UPDATE,
|
||||
TIM2_COUNTERCOMPARE_1,
|
||||
TIM2_COUNTERCOMPARE_2,
|
||||
TIM2_COUNTERCOMPARE_3,
|
||||
TIM2_COUNTERCOMPARE_4,
|
||||
TIM2_TRIGGER,
|
||||
TIM2_CAPTURECOMPARE_1,
|
||||
TIM2_CAPTURECOMPARE_2,
|
||||
TIM2_CAPTURECOMPARE_3,
|
||||
TIM2_CAPTURECOMAPRE_4,
|
||||
TIM3_UPDATE,
|
||||
TIM3_COUNTERCOMPARE_1,
|
||||
TIM3_COUNTERCOMPARE_2,
|
||||
TIM3_COUNTERCOMPARE_3,
|
||||
TIM3_COUNTERCOMPARE_4,
|
||||
TIM3_TRIGGER,
|
||||
TIM3_CAPTURECOMPARE_1,
|
||||
TIM3_CAPTURECOMPARE_2,
|
||||
TIM3_CAPTURECOMPARE_3,
|
||||
TIM3_CAPTURECOMAPRE_4,
|
||||
TIM14_CAPTURECOMPARE_1_OVERCAPTURE,
|
||||
TIM14_CAPTURECOMPARE_1,
|
||||
TIM14_UPDATE,
|
||||
TIM16_CAPTURECOMPARE_1_OVERCAPTURE,
|
||||
TIM16_BREAK,
|
||||
TIM16_COMMUNICATION,
|
||||
TIM16_CAPTURECOMPARE_1,
|
||||
TIM16_UPDATE,
|
||||
TIM17_CAPTURECOMPARE_1_OVERCAPTURE,
|
||||
TIM17_BREAK,
|
||||
TIM17_COMMUNICATION,
|
||||
TIM17_CAPTURECOMPARE_1,
|
||||
TIM17_UPDATE,
|
||||
SPI1_TX_FIFO_EMPTY,
|
||||
SPI1_TX_FIFO_1_4,
|
||||
SPI1_TX_FIFO_1_2,
|
||||
SPI1_TX_FIFO_FULL,
|
||||
SPI1_RX_FIFO_EMPTY,
|
||||
SPI1_RX_FIFO_1_4,
|
||||
SPI1_RX_FIFO_1_2,
|
||||
SPI1_RX_FIFO_FULL,
|
||||
SPI1_FRAME_FORMAT_ERROR,
|
||||
SPI1_BUSY,
|
||||
SPI1_OVERRUN,
|
||||
SPI1_MODE_FAULT,
|
||||
SPI1_CRC_ERROR,
|
||||
SPI1_UNDERRUN,
|
||||
SPI1_CHANNEL_SIDE,
|
||||
SPI1_TX_BUFFER_EMPTY,
|
||||
SPI1_RX_BUFFER_NOT_EMPTY,
|
||||
intTypeEND
|
||||
}intrType_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _HWD_INTERRUPT_H_
|
@ -0,0 +1,70 @@
|
||||
/**
|
||||
**************************************************************************************************
|
||||
* @file hwd_spi.h
|
||||
* @author Kerem Yollu & Edwin Koch
|
||||
* @date 26.02.2023
|
||||
* @version 1.0
|
||||
**************************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* **Detailed Description :**
|
||||
*
|
||||
**************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _HWD_SPI_H_
|
||||
#define _HWD_SPI_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hardwareDescription.h"
|
||||
|
||||
#define MAX_SPI_CHANNEL_COUNT 2
|
||||
|
||||
/*!
|
||||
* RCC Bus number index list connected to the SPI
|
||||
* */
|
||||
static const uint8_t spiBus_No[MAX_SPI_CHANNEL_COUNT] = {
|
||||
2, /*!< SPI 1 is connected to bus 2 */
|
||||
1 /*!< SPI 2 is connected to bus 1 */
|
||||
};
|
||||
|
||||
/*!
|
||||
* RCC SPI clock enable bit position for the given register
|
||||
*
|
||||
*/
|
||||
static const uint8_t spiBus_En_bitPos[MAX_SPI_CHANNEL_COUNT] = {
|
||||
RCC_APB2ENR_SPI1EN_Pos,
|
||||
RCC_APB1ENR_SPI2EN_Pos
|
||||
};
|
||||
|
||||
/*!
|
||||
* RCC SPI Reset Bit Position list
|
||||
* */
|
||||
static const uint8_t spiBus_Rst_bitPos[MAX_SPI_CHANNEL_COUNT] = {
|
||||
RCC_APB2RSTR_SPI1RST_Pos,
|
||||
RCC_APB1RSTR_SPI2RST_Pos
|
||||
};
|
||||
|
||||
/**
|
||||
* Enumof available spi hardware channels
|
||||
*/
|
||||
typedef enum{
|
||||
SPI_CH_1,
|
||||
SPI_CH_2
|
||||
} spiCH_t;
|
||||
/**
|
||||
* SPI base address list
|
||||
*/
|
||||
static const uint32_t spiBase_Addr_List[MAX_SPI_CHANNEL_COUNT] = {
|
||||
SPI1_BASE,
|
||||
SPI2_BASE
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _HWD_SPI_H_
|
@ -0,0 +1,105 @@
|
||||
/**
|
||||
**************************************************************************************************
|
||||
* @file hwd_timer.h
|
||||
* @author Kerem Yollu & Edwin Koch
|
||||
* @date 26.02.2023
|
||||
* @version 1.0
|
||||
**************************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* **Detailed Description :**
|
||||
*
|
||||
**************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _HWD_TIMER_H_
|
||||
#define _HWD_TIMER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hardwareDescription.h"
|
||||
|
||||
#define MAX_TIMER_CHANNEL_COUNT 6
|
||||
|
||||
/*!
|
||||
* Enum for awailable timer DS Page: 12 (block diagaram) The order of the enums is very important
|
||||
* and should not be changed as it is used ofr table indexing
|
||||
* */
|
||||
typedef enum {
|
||||
timer_1, /*!< Advanced control 16-bit timer with PWM capability RM Page: 320 */
|
||||
timer_2, /*!< General purpose 32-bit timer RM Page: 393 */
|
||||
timer_3, /*!< General purpose 16-bit timer RM Page: 393 */
|
||||
timer_14, /*!< General purpose 16-bit timer RM Page: 459 */
|
||||
timer_16, /*!< General purpose 16-bit timer RM Page: 480 */
|
||||
timer_17 /*!< General purpose 16-bit timer RM Page: 480 */
|
||||
} timerNo_t;
|
||||
|
||||
|
||||
/*!
|
||||
* Timer base addresslist of all available timers
|
||||
* */
|
||||
static const uint32_t timerBase_Addr_List[MAX_TIMER_CHANNEL_COUNT] = {
|
||||
TIM1_BASE, /*!< Timer 1 Base Address */
|
||||
TIM2_BASE, /*!< Timer 2 Base Address */
|
||||
TIM3_BASE, /*!< Timer 3 Base Address */
|
||||
TIM14_BASE, /*!< Timer 14 Base Address */
|
||||
TIM16_BASE, /*!< Timer 16 Base Address */
|
||||
TIM17_BASE /*!< Timer 17 Base Address */
|
||||
};
|
||||
|
||||
/*!
|
||||
* RCC clock enable bit position for the given register
|
||||
* */
|
||||
static const uint8_t timerBus_En_bitPos[MAX_TIMER_CHANNEL_COUNT] = {
|
||||
RCC_APB2ENR_TIM1EN_Pos,
|
||||
RCC_APB1ENR_TIM2EN_Pos,
|
||||
RCC_APB1ENR_TIM3EN_Pos,
|
||||
RCC_APB1ENR_TIM14EN_Pos,
|
||||
RCC_APB2ENR_TIM16EN_Pos,
|
||||
RCC_APB2ENR_TIM17EN_Pos
|
||||
};
|
||||
|
||||
/*!
|
||||
* RCC timer Reset Bit Position list
|
||||
* */
|
||||
static const uint8_t timerBus_Rst_bitPos[MAX_TIMER_CHANNEL_COUNT] = {
|
||||
RCC_APB2RSTR_TIM1RST_Pos,
|
||||
RCC_APB1RSTR_TIM2RST_Pos,
|
||||
RCC_APB1RSTR_TIM3RST_Pos,
|
||||
RCC_APB1RSTR_TIM14RST_Pos,
|
||||
RCC_APB2RSTR_TIM16RST_Pos,
|
||||
RCC_APB2RSTR_TIM17RST_Pos
|
||||
};
|
||||
|
||||
/*!
|
||||
* RCC Bus number index list connected to the timer
|
||||
* */
|
||||
static const uint8_t timerBus_No[MAX_TIMER_CHANNEL_COUNT] = {
|
||||
2, /*!< timer 1 is connected to bus 2 */
|
||||
1, /*!< timer 2 is connected to bus 1 */
|
||||
1, /*!< timer 3 is connected to bus 1 */
|
||||
1, /*!< timer 14 is connected to bus 1 */
|
||||
2, /*!< timer 16 is connected to bus 2 */
|
||||
2 /*!< timer 17 is connected to bus 2 */
|
||||
};
|
||||
|
||||
/*!
|
||||
* Timer Prescaler resolution list TO BE DELETED IF NOT NEEDED
|
||||
* */
|
||||
static const uint32_t timerRes_Prescaler[MAX_TIMER_CHANNEL_COUNT] = {
|
||||
0xFFFF, /*!< Timer 1 Prescaler Max Value */
|
||||
0xFFFF, /*!< Timer 2 Prescaler Max Value */
|
||||
0xFFFF, /*!< Timer 3 Prescaler Max Value */
|
||||
0xFFFF, /*!< Timer 14 Prescaler Max Value */
|
||||
0xFFFF, /*!< Timer 16 Prescaler Max Value */
|
||||
0xFFFF, /*!< Timer 17 Prescaler Max Value */
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _HWD_TIMER_H_
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
**************************************************************************************************
|
||||
* @file hwd_usart.h
|
||||
* @author Kerem Yollu & Edwin Koch
|
||||
* @date 26.02.2023
|
||||
* @version 1.0
|
||||
**************************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* **Detailed Description :**
|
||||
*
|
||||
**************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _HWD_USART_H_
|
||||
#define _HWD_USART_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hardwareDescription.h"
|
||||
|
||||
#define MAX_USART_CHANNEL_COUNT 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _HWD_USART_H_
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1,153 @@
|
||||
#include "interrupt.h"
|
||||
#include "hwd_interrupt.h"
|
||||
#include "pin.h"
|
||||
|
||||
volatile void (*intHandlerArray[intTypeEND])() = {NULL};
|
||||
|
||||
|
||||
const uint8_t interruptTypeIndexList[intTypeEND] =
|
||||
{
|
||||
EXTI0_1_IRQn,
|
||||
EXTI0_1_IRQn,
|
||||
EXTI0_1_IRQn,
|
||||
EXTI0_1_IRQn,
|
||||
EXTI0_1_IRQn,
|
||||
EXTI2_3_IRQn,
|
||||
EXTI2_3_IRQn,
|
||||
EXTI2_3_IRQn,
|
||||
EXTI2_3_IRQn,
|
||||
EXTI2_3_IRQn,
|
||||
EXTI2_3_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn,
|
||||
TIM1_BRK_UP_TRG_COM_IRQn,
|
||||
TIM1_BRK_UP_TRG_COM_IRQn,
|
||||
TIM1_BRK_UP_TRG_COM_IRQn,
|
||||
TIM1_BRK_UP_TRG_COM_IRQn,
|
||||
TIM1_CC_IRQn,
|
||||
TIM1_CC_IRQn,
|
||||
TIM1_CC_IRQn,
|
||||
TIM1_CC_IRQn,
|
||||
TIM2_IRQn,
|
||||
TIM2_IRQn,
|
||||
TIM2_IRQn,
|
||||
TIM2_IRQn,
|
||||
TIM2_IRQn,
|
||||
TIM2_IRQn,
|
||||
TIM2_IRQn,
|
||||
TIM2_IRQn,
|
||||
TIM2_IRQn,
|
||||
TIM2_IRQn,
|
||||
TIM3_IRQn,
|
||||
TIM3_IRQn,
|
||||
TIM3_IRQn,
|
||||
TIM3_IRQn,
|
||||
TIM3_IRQn,
|
||||
TIM3_IRQn,
|
||||
TIM3_IRQn,
|
||||
TIM3_IRQn,
|
||||
TIM3_IRQn,
|
||||
TIM3_IRQn,
|
||||
TIM14_IRQn,
|
||||
TIM14_IRQn,
|
||||
TIM14_IRQn,
|
||||
TIM16_IRQn,
|
||||
TIM16_IRQn,
|
||||
TIM16_IRQn,
|
||||
TIM16_IRQn,
|
||||
TIM16_IRQn,
|
||||
TIM17_IRQn,
|
||||
TIM17_IRQn,
|
||||
TIM17_IRQn,
|
||||
TIM17_IRQn,
|
||||
TIM17_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn,
|
||||
SPI1_IRQn
|
||||
};
|
||||
|
||||
void intInit(
|
||||
intrType_t intType,
|
||||
intHandler_t handler,
|
||||
uint8_t priority)
|
||||
{
|
||||
// check if index is correct
|
||||
if(intType >= intTypeEND) return;
|
||||
|
||||
intDisableGlobal();
|
||||
|
||||
NVIC_SetPriority(interruptTypeIndexList[intType], priority);
|
||||
intHandlerArray[intType] = handler;
|
||||
|
||||
}
|
||||
|
||||
void intEnableGlobal()
|
||||
{
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
void intDisableGlobal()
|
||||
{
|
||||
__disable_irq();
|
||||
}
|
||||
|
||||
void intEnable(
|
||||
intrType_t intType)
|
||||
{
|
||||
NVIC_EnableIRQ(interruptTypeIndexList[intType]);
|
||||
}
|
||||
|
||||
void intDissable(
|
||||
intrType_t intType)
|
||||
{
|
||||
NVIC_DisableIRQ(interruptTypeIndexList[intType]);
|
||||
}
|
||||
|
@ -0,0 +1,161 @@
|
||||
#include "spi.h"
|
||||
#include "hardwareDescription.h"
|
||||
#include "hwd_spi.h"
|
||||
#include "interrupt.h"
|
||||
|
||||
#define SPI_BASE ((SPI_TypeDef *)spiBase_Addr_List[spi_hw_ch])
|
||||
|
||||
void spiReset(spiCH_t spi_hw_ch)
|
||||
{
|
||||
if(spiBus_No[spi_hw_ch] == 1) {
|
||||
RCC->APB1RSTR |= (1 << spiBus_Rst_bitPos[spi_hw_ch]);
|
||||
RCC->APB1RSTR &= ~(1 << spiBus_Rst_bitPos[spi_hw_ch]);
|
||||
return;
|
||||
}
|
||||
|
||||
RCC->APB2RSTR |= (1 << spiBus_Rst_bitPos[spi_hw_ch]);
|
||||
RCC->APB2RSTR &= ~(1 << spiBus_Rst_bitPos[spi_hw_ch]);
|
||||
}
|
||||
|
||||
void spiEnableBus(spiCH_t spi_hw_ch)
|
||||
{
|
||||
if(spiBus_No[spi_hw_ch] == 1) {
|
||||
RCC->APB1ENR |= (1 << spiBus_En_bitPos[spi_hw_ch]);
|
||||
return;
|
||||
}
|
||||
|
||||
RCC->APB2ENR |= (1 << spiBus_En_bitPos[spi_hw_ch]);
|
||||
}
|
||||
|
||||
void spiEnable(spiCH_t spi_hw_ch)
|
||||
{
|
||||
SPI_BASE->CR1 |= SPI_CR1_SPE;
|
||||
}
|
||||
|
||||
void spiDissable(spiCH_t spi_hw_ch)
|
||||
{
|
||||
// TODO: implement p.768 procedure for dissabling
|
||||
//while(SPI_BASE->SR
|
||||
SPI_BASE->CR1 &= ~SPI_CR1_SPE;
|
||||
}
|
||||
|
||||
void spiSetMode(spiCH_t spi_hw_ch, spi_mode_t mode)
|
||||
{
|
||||
SPI_BASE->CR1 &= ~(mode << SPI_CR1_MSTR_Pos);
|
||||
SPI_BASE->CR1 |= mode << SPI_CR1_MSTR_Pos;
|
||||
|
||||
// TODO: find out if this is the correct place to set the SSOE bit
|
||||
SPI_BASE->CR2 &= ~SPI_CR2_SSOE;
|
||||
if(mode == SPI_MASTER) {
|
||||
SPI_BASE->CR2 |= SPI_CR2_SSOE;
|
||||
}
|
||||
}
|
||||
|
||||
void spiSetPolarity(spiCH_t spi_hw_ch, spi_clkPol_t clkPol)
|
||||
{
|
||||
// reset
|
||||
SPI_BASE->CR1 &= ~SPI_CR1_CPOL;
|
||||
// set
|
||||
SPI_BASE->CR1 |= clkPol << SPI_CR1_CPOL_Pos;
|
||||
}
|
||||
|
||||
void spiSetPhase(spiCH_t spi_hw_ch, spi_phase_t phase)
|
||||
{
|
||||
// reset
|
||||
SPI_BASE->CR1 &= ~(phase << SPI_CR1_CPHA_Pos);
|
||||
// set
|
||||
SPI_BASE->CR1 |= phase << SPI_CR1_CPHA_Pos;
|
||||
}
|
||||
|
||||
void spiSetBitFrameLength(spiCH_t spi_hw_ch, spi_framel_t framel)
|
||||
{
|
||||
|
||||
SPI_BASE->CR2 &= ~(SPI_CR2_FRXTH | SPI_CR2_DS);
|
||||
|
||||
// using p.974 as example
|
||||
if(framel == SPI_FRAME_LENGTH_8BIT) {
|
||||
// set FIFO reception threshold to 8 bit
|
||||
SPI_BASE->CR2 |= SPI_CR2_FRXTH;
|
||||
// set transfer lwnght to 8 bit
|
||||
SPI_BASE->CR2 |= SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2;
|
||||
return;
|
||||
}
|
||||
SPI_BASE->CR2 |= SPI_CR2_DS;
|
||||
}
|
||||
|
||||
void spiSetFrameFormat(spiCH_t spi_hw_ch, spi_framef_t framef)
|
||||
{
|
||||
// reset
|
||||
SPI_BASE->CR1 &= ~SPI_CR1_LSBFIRST;
|
||||
// set
|
||||
SPI_BASE->CR1 |= framef << SPI_CR1_LSBFIRST_Pos;
|
||||
}
|
||||
|
||||
spi_framef_t spiGetFrameFormat(spiCH_t spi_hw_ch)
|
||||
{
|
||||
return (spi_framef_t)(SPI_BASE->CR1 & SPI_CR1_LSBFIRST) >> SPI_CR1_LSBFIRST_Pos;
|
||||
}
|
||||
|
||||
void spiSetClockPrescaler(spiCH_t spi_hw_ch, uint32_t clkDiv)
|
||||
{
|
||||
// reset
|
||||
SPI_BASE->CR1 &= ~SPI_CR1_BR;
|
||||
// set
|
||||
SPI_BASE->CR1 |= (clkDiv << SPI_CR1_BR_Pos) & SPI_CR1_BR;
|
||||
}
|
||||
|
||||
void spiSetComMode(spiCH_t spi_hw_ch, spi_comMode_t comMode)
|
||||
{
|
||||
// reset
|
||||
SPI_BASE->CR1 &= ~SPI_CR1_RXONLY;
|
||||
// set
|
||||
SPI_BASE->CR1 |= comMode << SPI_CR1_RXONLY_Pos;
|
||||
}
|
||||
|
||||
void spiSetSoftwareSlaveManagement(spiCH_t spi_hw_ch, uint8_t logic)
|
||||
{
|
||||
SPI_BASE->CR1 &= ~SPI_CR1_SSM;
|
||||
|
||||
if(logic){
|
||||
SPI_BASE->CR1 |= SPI_CR1_SSM;
|
||||
}
|
||||
}
|
||||
|
||||
void spiSetInternalSlaveSelect(spiCH_t spi_hw_ch, uint8_t logic)
|
||||
{
|
||||
SPI_BASE->CR1 &= ~SPI_CR1_SSI;
|
||||
|
||||
if(logic) {
|
||||
SPI_BASE->CR1 |= SPI_CR1_SSI;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t spiTrx8BitPolling(spiCH_t spi_hw_ch, uint8_t tx_data)
|
||||
{
|
||||
// wait for BSY bit to Reset -> This will indicate that SPI is not busy in communication
|
||||
while (SPI_BASE->SR & SPI_SR_BSY);
|
||||
|
||||
// from example code p.975 f
|
||||
// this masking must be done. otherwise 16bits frame will be used
|
||||
*(uint8_t*)&(SPI_BASE->DR) = tx_data;
|
||||
|
||||
// Wait for RXNE to set -> This will indicate that the Rx buffer is not empty
|
||||
while (!(SPI_BASE->SR &SPI_SR_RXNE));
|
||||
|
||||
|
||||
// TODO: test read!
|
||||
return *(uint8_t*)&(SPI_BASE->DR);
|
||||
}
|
||||
|
||||
// Interrupt Service Routines
|
||||
|
||||
void SPI1_IRQHandle()
|
||||
{
|
||||
//HANDLE_INT_FLAG(SPI1->SR, );
|
||||
}
|
||||
|
||||
void SPI2_IRQHandle()
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
set(DRIVERS_LIST lcd_oled max7219 max31865 ssd1306_i2c)
|
@ -0,0 +1,96 @@
|
||||
# Drivers
|
||||
## Description
|
||||
Drivers are the higher level of code provided by *KED*. It comes on top of the [Peripherals](https://git.keydev.me/kerem/KED/src/branch/master/peripherals) and alows the usage of comercially awailable IC's or moludes.
|
||||
|
||||
---
|
||||
## Please follow this guide to find out about the :
|
||||
- [Structure](#structure)
|
||||
- [Usage](#usage)
|
||||
- [Creation](#creation)
|
||||
- [Modification](#modification)
|
||||
- [Credits](#credits)
|
||||
- [License](#license)
|
||||
---
|
||||
|
||||
## Structure
|
||||
##### The __driver__ folder has multiple elements inside :
|
||||
+ CMakeLists.txt
|
||||
+ where the DRIVERS_LIST is defined
|
||||
+ Folders named after the driver that they respresent. Inside you will find:
|
||||
+ Source file of the driver
|
||||
+ Header file of the driver
|
||||
+ This Readme file
|
||||
---
|
||||
|
||||
## Usage
|
||||
In the *CMakeLists.txt* you will find the decalarion of __DRIVERS_LIST__ list which contains the dirvers that are to be compiled.
|
||||
The *name* of the declared *driver* also defines the name of the driver's *folder*, *souce* file and *header* file.
|
||||
Once the driver is implemented correctly you can call the header of the driver from any soure of header file.
|
||||
> exmaple for *ssd1306_i2c*
|
||||
~~~ C
|
||||
#include "ssd1306_i2c.h"
|
||||
~~~
|
||||
|
||||
CMake will the automatically find the driver, compile it and implement it to the main projet as a submodule.
|
||||
|
||||
---
|
||||
## Creation
|
||||
### Let's implement a driver named *ssd1306_i2c*
|
||||
#### First let's add *ssd1306_i2c* to the __DRIVERS_LIST__.
|
||||
Open *CMakeLists.txt* with your favorite *text editor* and modifiy the line wehre __DRIVERS_LIST__ is defined.
|
||||
In which order the drivers are added to the list has no importance.
|
||||
|
||||
> Before adding *ssd1306_i2c*
|
||||
|
||||
~~~ CMAKE
|
||||
set(DRIVERS_LIST lcd_oled max7219 max31865)
|
||||
~~~
|
||||
|
||||
> After adding *ssd1306_i2c* the declaration of __DRIVERS_LIST__ should look like this
|
||||
|
||||
~~~ CMAKE
|
||||
set(DRIVERS_LIST lcd_oled max7219 max31865 ssd1306_i2c)
|
||||
~~~
|
||||
|
||||
#### Than we can create a folder with the same name
|
||||
~~~ bash
|
||||
mkdir ssd1306_i2c
|
||||
~~~
|
||||
|
||||
#### Inside the newly created folder add the *source* and *header* file with the same name as the driver
|
||||
In our case that means __ssd1306_i2c.c__ and __ssd1306_i2c.h__
|
||||
|
||||
~~~ bash
|
||||
touch ssd1306_i2c.c ssd1306_i2c.h
|
||||
~~~
|
||||
|
||||
#### The final structure should look like this
|
||||
As you can see this folder also contains the datashhed for this driver. If you have any additional documentation like a datasheet or calculation sheet, feel free to add them here.
|
||||
|
||||
~~~ bash
|
||||
└── ssd1306_i2c
|
||||
├── ssd1306_i2c.c
|
||||
├── ssd1306_i2c.h
|
||||
└── SSD1306.pdf
|
||||
~~~
|
||||
---
|
||||
## Modification
|
||||
You can modify each driver to your convinience but it can't be pushed again so please be careful during GIT transactions.
|
||||
You can also remove any driver from the complation by simply removing his declaration from the __DRIVERS_LIST__
|
||||
> Like so :
|
||||
set(DRIVERS_LIST lcd_oled max7219 max31865 ~~ssd1306_i2c~~)
|
||||
## How to Contribute
|
||||
Do you want to become a contibutor ? :
|
||||
How is Ked organised :
|
||||
Rules to write a Driver :
|
||||
|
||||
## Credits
|
||||
|
||||
Edwin Koch
|
||||
Kerem Yollu
|
||||
|
||||
## License
|
||||
|
||||
The last section of a high-quality README file is the license. This lets other developers know what they can and cannot do with your project. If you need help choosing a license, refer to [https://choosealicense.com/](https://choosealicense.com/).
|
||||
|
||||
---
|
@ -0,0 +1,357 @@
|
||||
#include "lcd_oled.h"
|
||||
#include "ssd1306_i2c.h"
|
||||
|
||||
i2c_t i2c_device = { I2C_CH_1, /*!< The harware channel to be used */
|
||||
i2c_mode_master, /*!< Master Mode */
|
||||
0x00, /*!< First and Main address of the device */
|
||||
0x00, /*!< Second address if dual addresse mode is configured */
|
||||
i2c_address_count_single, /*!< Single address */
|
||||
i2c_address_size_7b, /*!< 10 or 7 bit address size */
|
||||
i2c_clk_speed_standart, /*!< Bus Speed: standart */
|
||||
i2c_clk_stretching_disable, /*!< Clock Streching disabeled */
|
||||
i2c_wake_disabled}; /*!< Wake up condition : None */
|
||||
|
||||
|
||||
#define pgm_read_byte(addr) (*(const uint8_t *)(addr))
|
||||
#define ssd1306_swap(a, b) { int16_t t = a; a = b; b = t; }
|
||||
#define ROTATION 0 // TODO: This shoudl be initiated at the function
|
||||
|
||||
uint8_t display_buffer[LCD_OLED_SIZE_X * LCD_OLED_SIZE_Y / 8] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
|
||||
0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF,
|
||||
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
|
||||
0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84, 0x00, 0x00, 0x80, 0xF8,
|
||||
0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80,
|
||||
0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0x01, 0x01,
|
||||
0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF,
|
||||
0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x7F, 0xFF,
|
||||
0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x8F,
|
||||
0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC,
|
||||
0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x01, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01,
|
||||
0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00,
|
||||
0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03,
|
||||
0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x0F,
|
||||
0x87, 0xC7, 0xF7, 0xFF, 0xFF, 0x1F, 0x1F, 0x3D, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0x7C, 0x7D, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x00, 0x30, 0x30, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F,
|
||||
0x0F, 0x07, 0x1F, 0x7F, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xE0,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00,
|
||||
0x00, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xF0, 0xF8, 0x1C, 0x0E,
|
||||
0x06, 0x06, 0x06, 0x0C, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFC,
|
||||
0xFE, 0xFC, 0x00, 0x18, 0x3C, 0x7E, 0x66, 0xE6, 0xCE, 0x84, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x06,
|
||||
0x06, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xC0, 0xF8,
|
||||
0xFC, 0x4E, 0x46, 0x46, 0x46, 0x4E, 0x7C, 0x78, 0x40, 0x18, 0x3C, 0x76, 0xE6, 0xCE, 0xCC, 0x80,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x03,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00,
|
||||
0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x03, 0x07, 0x0E, 0x0C,
|
||||
0x18, 0x18, 0x0C, 0x06, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0E, 0x0C, 0x18, 0x0C, 0x0F,
|
||||
0x07, 0x01, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00,
|
||||
0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x07,
|
||||
0x07, 0x0C, 0x0C, 0x18, 0x1C, 0x0C, 0x06, 0x06, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
void lcd_oled_init(i2c_t *i2c_dev, uint8_t address)
|
||||
{
|
||||
|
||||
i2c_init(&i2c_device);
|
||||
ssd1306_i2c_set_display_off(i2c_dev);
|
||||
ssd1306_i2c_set_display_clkDiv_oscFreq(i2c_dev, 0, 15); // Working but to be refined
|
||||
ssd1306_i2c_set_multiplex_ratio(i2c_dev, LCD_OLED_SIZE_Y - 1); // Pages start at 0 and ends at 63
|
||||
ssd1306_i2c_set_display_offset(i2c_dev, 0x00); // No Offset
|
||||
ssd1306_i2c_set_display_start_line(i2c_dev, 0); // Start line 0
|
||||
ssd1306_i2c_set_chage_pump(i2c_dev, SSD1306_SWITCHCAPVCC);
|
||||
ssd1306_i2c_set_memory_addressing_mode(i2c_dev, SSD1306_MEMORY_MODE_HORIZONTAL);
|
||||
ssd1306_i2c_set_segment_remap(i2c_dev, 1);
|
||||
ssd1306_i2c_set_com_scan_direction(i2c_dev, 0); //Decremental TODO : Make a define for it
|
||||
ssd1306_i2c_set_com_pins(i2c_dev, SSD1306_COM_SEQ_LR_REMAP_ON);
|
||||
ssd1306_i2c_set_contrast(i2c_dev,0x9F);
|
||||
ssd1306_i2c_set_prechage_period(i2c_dev, 0xF0); // TODO : I don't know what he exxect is
|
||||
ssd1306_i2c_set_com_deselect_level(i2c_dev, 0x40); // TODO : PLeanty of things can influance this capacitor value being the most importnat one
|
||||
ssd1306_i2c_set_display_entire_on(i2c_dev, SSD1306_DISPLAYALLON_RESUME);
|
||||
ssd1306_i2c_set_display_invert_pixel(i2c_dev, 0); // Normal pilex printing. Warning this hurts the eye
|
||||
ssd1306_i2c_set_scroll(i2c_dev, 0);// Turn scrolling off
|
||||
ssd1306_i2c_set_display_on(i2c_dev);
|
||||
}
|
||||
|
||||
uint8_t lcd_oled_clear()
|
||||
{
|
||||
memset(display_buffer, 0,(LCD_OLED_SIZE_X * LCD_OLED_SIZE_Y / 8) * sizeof(uint8_t));
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t lcd_oled_display()
|
||||
{
|
||||
ssd1306_i2c_send_command(&i2c_device,SSD1306_COLUMNADDR);
|
||||
ssd1306_i2c_send_command(&i2c_device,0); // Column start address (0 = reset)
|
||||
ssd1306_i2c_send_command(&i2c_device,LCD_OLED_SIZE_X - 1); // Column end address (127
|
||||
// = reset)
|
||||
|
||||
ssd1306_i2c_send_command(&i2c_device,SSD1306_PAGEADDR);
|
||||
ssd1306_i2c_send_command(&i2c_device,0); // Page start address (0 = reset)
|
||||
ssd1306_i2c_send_command(&i2c_device,7); // Page end address
|
||||
|
||||
uint8_t i2cDataLenght = 1; // Co = 0, D/C = 0
|
||||
uint16_t address = SSD1306_I2C_ADDRESS; // Co = 0, D/C = 0
|
||||
uint8_t reg = 0x40;
|
||||
// I2C
|
||||
int16_t i;
|
||||
for (i = 0; i < (LCD_OLED_SIZE_X * SSD1306_LCDHEIGHT / 8); i++) {
|
||||
i2c_write(&i2c_device, &address, ®, &display_buffer[i], &i2cDataLenght);
|
||||
//This sends byte by byte.
|
||||
//Better to send all buffer
|
||||
//Should be optimized
|
||||
}
|
||||
/*
|
||||
uint16_t i2cDataLenght = (LCD_OLED_SIZE_X * SSD1306_LCDHEIGHT / 8) -1 ; // Co = 0, D/C = 0
|
||||
uint16_t address = SSD1306_I2C_ADDRESS; // Co = 0, D/C = 0
|
||||
uint8_t reg = 0x40;
|
||||
i2c_write(&i2c_device, &address, ®, &display_buffer, &i2cDataLenght);
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
void lcd_oled_print_char(uint16_t x, uint16_t y, uint8_t c, uint8_t color)
|
||||
{
|
||||
uint8_t size = 1;
|
||||
if ((x >= WIDTH) || // Clip right
|
||||
(y >= HEIGHT) || // Clip bottom
|
||||
((x + 6 * size - 1) < 0) || // Clip left
|
||||
((y + 8 * size - 1) < 0)) // Clip top
|
||||
return;
|
||||
int16_t i;
|
||||
int16_t j;
|
||||
for (i = 0; i < 6; i++) {
|
||||
int16_t line;
|
||||
if (i == 5)
|
||||
line = 0x0;
|
||||
else
|
||||
line = (*(const uint8_t *)(font + (c * 5) + i));
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (line & 0x1) {
|
||||
if (size == 1) // default size
|
||||
lcd_oled_draw_pixel(x + i, y + j, color);
|
||||
else { // big size To implement
|
||||
//ssd1306_fillRect(x + (i * size),
|
||||
// y + (j * size), size,
|
||||
// size, color);
|
||||
}
|
||||
}
|
||||
line >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_oled_draw_pixel(uint16_t x, uint16_t y, uint8_t color)
|
||||
{
|
||||
if ((x < 0) || (x >= LCD_OLED_SIZE_X) || (y < 0) || (y >= LCD_OLED_SIZE_Y))
|
||||
return;
|
||||
|
||||
// check rotation, move pixel around if necessary
|
||||
switch (ROTATION) {
|
||||
case 1:
|
||||
ssd1306_swap(x, y);
|
||||
x = LCD_OLED_SIZE_X - x - 1;
|
||||
break;
|
||||
case 2:
|
||||
x = LCD_OLED_SIZE_X - x - 1;
|
||||
y = LCD_OLED_SIZE_Y - y - 1;
|
||||
break;
|
||||
case 3:
|
||||
ssd1306_swap(x, y);
|
||||
y = LCD_OLED_SIZE_Y - y - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// x is which column
|
||||
switch (color) {
|
||||
case WHITE:
|
||||
display_buffer[x + (y / 8) * LCD_OLED_SIZE_X] |= (1 << (y & 7));
|
||||
break;
|
||||
case BLACK:
|
||||
display_buffer[x + (y / 8) * LCD_OLED_SIZE_X] &= ~(1 << (y & 7));
|
||||
break;
|
||||
case INVERSE:
|
||||
display_buffer[x + (y / 8) * LCD_OLED_SIZE_X] ^= (1 << (y & 7));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_oled_print_text(uint16_t x, uint16_t y, uint8_t *text, uint16_t length, uint8_t color)
|
||||
{
|
||||
uint8_t pos, i = 0;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
pos = x + (i * 6);
|
||||
lcd_oled_print_char(pos,y,text[i],color);
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_oled_draw_line(uint16_t x, uint16_t y, uint16_t angle, uint16_t lenght, uint8_t color)
|
||||
{
|
||||
int16_t i = 0;
|
||||
|
||||
switch(angle)
|
||||
{
|
||||
case 0:
|
||||
case 360:
|
||||
for(i = 0; i < lenght; i++)
|
||||
{
|
||||
lcd_oled_draw_pixel(x+i,y,color);
|
||||
}
|
||||
break;
|
||||
case 45:
|
||||
for(i = 0; i < lenght; i++)
|
||||
{
|
||||
lcd_oled_draw_pixel(x+i,y-i,color);
|
||||
}
|
||||
break;
|
||||
case 90:
|
||||
for(i = 0; i < lenght; i++)
|
||||
{
|
||||
lcd_oled_draw_pixel(x,y-i,color);
|
||||
}
|
||||
break;
|
||||
case 135:
|
||||
for(i = 0; i < lenght; i++)
|
||||
{
|
||||
lcd_oled_draw_pixel(x-i,y-i,color);
|
||||
}
|
||||
break;
|
||||
case 180:
|
||||
for(i = 0; i < lenght; i++)
|
||||
{
|
||||
lcd_oled_draw_pixel(x-i,y,color);
|
||||
}
|
||||
break;
|
||||
case 225:
|
||||
for(i = 0; i < lenght; i++)
|
||||
{
|
||||
lcd_oled_draw_pixel(x-i,y+i,color);
|
||||
}
|
||||
break;
|
||||
case 270:
|
||||
for(i = 0; i < lenght; i++)
|
||||
{
|
||||
lcd_oled_draw_pixel(x,y+i,color);
|
||||
}
|
||||
break;
|
||||
case 315:
|
||||
for(i = 0; i < lenght; i++)
|
||||
{
|
||||
lcd_oled_draw_pixel(x+i,y+i,color);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_oled_draw_circle(uint16_t x, uint16_t y, uint16_t radius, uint8_t fill, uint8_t color)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
int16_t x_cicle, y_circle, d = 0;
|
||||
if(fill == 0)
|
||||
{
|
||||
x_cicle = 0;
|
||||
y_circle = radius;
|
||||
d = 3 - 2 * radius;
|
||||
lcd_oled_draw_circle_bresenham(x, y, x_cicle, y_circle, color);
|
||||
while (y_circle >= x_cicle)
|
||||
{
|
||||
x_cicle++;
|
||||
if (d > 0)
|
||||
{
|
||||
y_circle--;
|
||||
d = d + 4 * (x_cicle - y_circle) + 10;
|
||||
}
|
||||
else
|
||||
d = d + 4 * x_cicle + 6;
|
||||
lcd_oled_draw_circle_bresenham(x, y, x_cicle, y_circle, color);
|
||||
}
|
||||
}
|
||||
else // To be optimized
|
||||
{
|
||||
for(i=radius; i > 0; i--)
|
||||
{
|
||||
x_cicle = 0;
|
||||
y_circle = i;
|
||||
d = 3 - 2 * i;
|
||||
lcd_oled_draw_circle_bresenham(x, y, x_cicle, y_circle, color);
|
||||
while (y_circle >= x_cicle)
|
||||
{
|
||||
x_cicle++;
|
||||
if (d > 0)
|
||||
{
|
||||
y_circle--;
|
||||
d = d + 4 * (x_cicle - y_circle) + 10;
|
||||
}
|
||||
else
|
||||
d = d + 4 * x_cicle + 6;
|
||||
lcd_oled_draw_circle_bresenham(x, y, x_cicle, y_circle, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_oled_draw_circle_bresenham(int16_t xc, int16_t yc, uint8_t x, uint8_t y, uint8_t color)
|
||||
{
|
||||
lcd_oled_draw_pixel(xc+x, yc+y, color);
|
||||
lcd_oled_draw_pixel(xc-x, yc+y, color);
|
||||
lcd_oled_draw_pixel(xc+x, yc-y, color);
|
||||
lcd_oled_draw_pixel(xc-x, yc-y, color);
|
||||
lcd_oled_draw_pixel(xc+y, yc+x, color);
|
||||
lcd_oled_draw_pixel(xc-y, yc+x, color);
|
||||
lcd_oled_draw_pixel(xc+y, yc-x, color);
|
||||
lcd_oled_draw_pixel(xc-y, yc-x, color);
|
||||
}
|
||||
|
||||
|
||||
void lcd_oled_draw_rectangle(uint16_t x, uint16_t y, uint16_t length, uint16_t width, uint8_t fill, uint8_t color)
|
||||
{
|
||||
uint16_t i = 0;
|
||||
if(fill == EMPTY)
|
||||
{
|
||||
lcd_oled_draw_line(x, y, 0, length, color);
|
||||
lcd_oled_draw_line(x, y+width-1, 0, length, color);
|
||||
lcd_oled_draw_line(x, y, 270, width, color);
|
||||
lcd_oled_draw_line(x+length-1, y, 270, width, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0 ; i < width; i++)
|
||||
{
|
||||
lcd_oled_draw_line(x, y+i, 0, length, color);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
#ifndef _LCD_OLED_H_
|
||||
#define _LCD_OLED_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "oled_fonts.h"
|
||||
|
||||
#define FILLED 1
|
||||
#define EMPTY 0
|
||||
|
||||
#define LCD_OLED_I2C
|
||||
|
||||
#define LCD_OLED_SIZE_X 128
|
||||
#define LCD_OLED_SIZE_Y 64
|
||||
|
||||
#if defined LCD_OLED_I2C
|
||||
#include "i2c.h"
|
||||
void lcd_oled_init(i2c_t *i2c_dev, uint8_t address);
|
||||
|
||||
#elif defined LCD_OLED_SPI
|
||||
#include "spi.h"
|
||||
void lcd_oled_init(spi_t *spi_dev, pinNo_t pinNo, uint8_t address);
|
||||
|
||||
#else
|
||||
#error "Please Define The communication Methode in ked/drivers/lcd_oled/lcd_oled.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void lcd_oled_enable();
|
||||
void lcd_oled_disable();
|
||||
|
||||
void lcd_oled_reset_hard();
|
||||
void lcd_oled_reset_soft();
|
||||
|
||||
uint8_t lcd_oled_is_ready();
|
||||
|
||||
void lcd_oled_sleep();
|
||||
void lcd_oled_wake();
|
||||
|
||||
void lcd_oled_draw_pixel(uint16_t x, uint16_t y, uint8_t color);
|
||||
void lcd_oled_draw_line(uint16_t x, uint16_t y, uint16_t angle, uint16_t lenght, uint8_t color);
|
||||
void lcd_oled_draw_rectangle(uint16_t x, uint16_t y, uint16_t length, uint16_t width, uint8_t fill, uint8_t color);
|
||||
void lcd_oled_draw_circle(uint16_t x, uint16_t y, uint16_t radius, uint8_t fill, uint8_t color);
|
||||
void lcd_oled_draw_circle_bresenham(int16_t xc, int16_t yc, uint8_t x, uint8_t y, uint8_t color);
|
||||
|
||||
void lcd_oled_scroll_right(uint16_t start, uint16_t stop);
|
||||
void lcd_oled_scroll_left(uint16_t start, uint16_t stop);
|
||||
|
||||
void lcd_oled_scroll_up(uint16_t start, uint16_t stop);
|
||||
void lcd_oled_scroll_down(uint16_t start, uint16_t stop);
|
||||
|
||||
void lcd_oled_set_font(uint8_t *font, uint8_t size, uint8_t spacing);
|
||||
void lcd_oled_print_char(uint16_t x, uint16_t y, uint8_t c, uint8_t color);
|
||||
void lcd_oled_print_text(uint16_t x, uint16_t y, uint8_t *text, uint16_t length, uint8_t color);
|
||||
void lcd_oled_print_cursor(uint8_t blink);
|
||||
|
||||
void lcd_oled_goto_pos(uint16_t x, uint16_t y);
|
||||
|
||||
uint8_t lcd_oled_display();
|
||||
uint8_t lcd_oled_clear();
|
||||
|
||||
void lcd_oled_change_brightness(uint8_t brightness);
|
||||
void lcd_oled_change_contrast(uint8_t contrast);
|
||||
|
||||
void lcd_oled_rotate(uint8_t angle);
|
||||
void lcd_oled_inverse(uint8_t yseNo);
|
||||
void lcd_oled_invert(uint8_t yseNo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LCD_OLED_H_ */
|
@ -0,0 +1,124 @@
|
||||
#include "max7219.h"
|
||||
|
||||
void max7219_init(
|
||||
max7219_t *display,
|
||||
spi_ch_t *spi_ch)
|
||||
{
|
||||
display->spiCH = spi_ch;
|
||||
}
|
||||
|
||||
void max7219_testDisplay(
|
||||
max7219_t *display,
|
||||
uint8_t logic)
|
||||
{
|
||||
spiWriteReg(display->spiCH,0x0F, (logic) ? 0x01 : 0x00);
|
||||
}
|
||||
|
||||
void max7219_shutdownDiaply(
|
||||
max7219_t *display,
|
||||
uint8_t logic)
|
||||
{
|
||||
spiWriteReg(display->spiCH,0x0C, (logic) ? 0x00 : 0x01);
|
||||
}
|
||||
|
||||
void max7219_setDecodeMode(
|
||||
max7219_t *display,
|
||||
max7219_decodeMode_t dmode)
|
||||
{
|
||||
spiWriteReg(display->spiCH,0x09,(uint8_t) dmode);
|
||||
}
|
||||
|
||||
void max7219_setIntensity(
|
||||
max7219_t *display,
|
||||
uint8_t intensity)
|
||||
{
|
||||
spiWriteReg(display->spiCH, 0x0A, intensity & 0x0F);
|
||||
}
|
||||
|
||||
void max7219_setScanLimit(
|
||||
max7219_t *display,
|
||||
max7219_scanLimit_t slimit)
|
||||
{
|
||||
spiWriteReg(display->spiCH, 0x0B, ((uint8_t) slimit) & 0x0F);
|
||||
}
|
||||
|
||||
void max7219_setAllLEDsOff(
|
||||
max7219_t *display)
|
||||
{
|
||||
uint8_t i;
|
||||
for(i = 0; i < 9; i++) {
|
||||
spiWriteReg(display->spiCH, i, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
void max7219_ledMatrixSetLED(
|
||||
max7219_t *display,
|
||||
uint8_t row,
|
||||
uint8_t col)
|
||||
{
|
||||
|
||||
//uint8_t val = 0xAE; // Unused variable warning commented by KeY
|
||||
|
||||
row = (row & 0x07) + 1;
|
||||
col = 1 << (col & 0x07);
|
||||
|
||||
spiWriteReg(display->spiCH, row,col);
|
||||
}
|
||||
|
||||
void max7219_rawWrite(
|
||||
max7219_t *display,
|
||||
uint8_t reg,
|
||||
uint8_t data)
|
||||
{
|
||||
spiWriteReg(display->spiCH, reg, data);
|
||||
}
|
||||
|
||||
void max7219_printLedMatrix(
|
||||
max7219_t *display,
|
||||
uint8_t matrix[])
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
for(i = 0; i < 8; i ++) {
|
||||
spiWriteReg(display->spiCH, i+1, matrix[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void max7219_ledMatrixUnsetLED(
|
||||
max7219_t *display,
|
||||
uint8_t row,
|
||||
uint8_t col)
|
||||
{
|
||||
row = (row & 0x07) + 1;
|
||||
col = 1 << (col & 0x07);
|
||||
// TODO: find out how to turn off LED
|
||||
spiWriteReg(display->spiCH, row,col+1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
// daysichained matrix
|
||||
typedef struct{
|
||||
spi_ch_t *spiCH;
|
||||
uint8_t nDevices;
|
||||
}max7219_dm_t;
|
||||
|
||||
|
||||
void max7219_dm_write(
|
||||
max7219_dm_t *matrix,
|
||||
uint8_t **data)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
uint8_t j = 0;
|
||||
// TODO: Test it out
|
||||
for(i = 0; i < 8; i++) {
|
||||
pinWrite(matrix->spiCH->pin, 0);
|
||||
for(j = 0; j < matrix->nDevices; j++) {
|
||||
spiTrx8BitPolling(matrix->spiCH->spi, i+1); // reg
|
||||
spiTrx8BitPolling(matrix->spiCH->spi, data[j][i]);
|
||||
}
|
||||
pinWrite(matrix->spiCH->pin, 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -0,0 +1,111 @@
|
||||
/**
|
||||
**************************************************************************************************
|
||||
* @file max7219.h
|
||||
* @author Kerem Yollu & Edwin Koch
|
||||
* @date 25.08.2022
|
||||
* @version 1.0
|
||||
**************************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* **Detailed Description :**
|
||||
*
|
||||
* @todo
|
||||
**************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _MAX7219_H_
|
||||
#define _MAX7219_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "spi.h"
|
||||
#include "pin.h"
|
||||
|
||||
typedef enum{
|
||||
NO_DECODE_DIGIT_7_TO_0 = 0x00,
|
||||
CODE_B_DECODE_ONLY_DIGIT_0 = 0x01,
|
||||
CODE_B_DECODE_ONLY_DIGIT_3_TO_0 = 0x0F,
|
||||
CODE_B_DECOD_DIGIT_7_TO_0 = 0xFF
|
||||
}max7219_decodeMode_t;
|
||||
|
||||
typedef enum{
|
||||
DISPLAY_DIGIT_0 = 0x00,
|
||||
DISPLAY_DIGIT_1_TO_0 = 0x01,
|
||||
DSIPLAX_DIGIT_2_TO_0 = 0x02,
|
||||
DSIPLAX_DIGIT_3_TO_0 = 0x03,
|
||||
DSIPLAX_DIGIT_4_TO_0 = 0x04,
|
||||
DSIPLAX_DIGIT_5_TO_0 = 0x05,
|
||||
DSIPLAX_DIGIT_6_TO_0 = 0x06,
|
||||
DSIPLAX_DIGIT_7_TO_0 = 0x07
|
||||
}max7219_scanLimit_t;
|
||||
|
||||
typedef struct{
|
||||
spi_ch_t *spiCH;
|
||||
}max7219_t;
|
||||
|
||||
void max7219_init(
|
||||
max7219_t *display,
|
||||
spi_ch_t *spi_ch);
|
||||
|
||||
void max7219_testDisplay(
|
||||
max7219_t *display,
|
||||
uint8_t logic);
|
||||
|
||||
void max7219_shutdownDiaply(
|
||||
max7219_t *display,
|
||||
uint8_t logic);
|
||||
|
||||
void max7219_setDecodeMode(
|
||||
max7219_t *display,
|
||||
max7219_decodeMode_t dmode);
|
||||
|
||||
void max7219_setIntensity(
|
||||
max7219_t *display,
|
||||
uint8_t intensity);
|
||||
|
||||
void max7219_setScanLimit(
|
||||
max7219_t *display,
|
||||
max7219_scanLimit_t slimit);
|
||||
|
||||
void max7219_setAllLEDsOff(
|
||||
max7219_t *display);
|
||||
|
||||
void max7219_ledMatrixSetLED(
|
||||
max7219_t *display,
|
||||
uint8_t row,
|
||||
uint8_t col);
|
||||
|
||||
void max7219_rawWrite(
|
||||
max7219_t *display,
|
||||
uint8_t reg,
|
||||
uint8_t data);
|
||||
|
||||
void max7219_printLedMatrix(
|
||||
max7219_t *display,
|
||||
uint8_t matrix[]);
|
||||
|
||||
void max7219_ledMatrixUnsetLED(
|
||||
max7219_t *display,
|
||||
uint8_t row,
|
||||
uint8_t col);
|
||||
#if 0
|
||||
// daysichained matrix
|
||||
typedef struct{
|
||||
spi_ch_t *spiCH;
|
||||
uint8_t nDevices;
|
||||
}max7219_dm_t;
|
||||
|
||||
|
||||
void max7219_dm_write(
|
||||
max7219_dm_t *matrix,
|
||||
uint8_t **data);
|
||||
#endif
|
||||
|
||||
#ifdef _cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _MAX7219_H_
|
@ -0,0 +1,126 @@
|
||||
#include "max7219.h"
|
||||
|
||||
void max7219_init(
|
||||
max7219_t *display,
|
||||
spi_ch_t *spi_ch)
|
||||
{
|
||||
display->spiCH = spi_ch;
|
||||
}
|
||||
|
||||
void h
|
||||
|
||||
void max7219_testDisplay(
|
||||
max7219_t *display,
|
||||
uint8_t logic)
|
||||
{
|
||||
spiWriteReg(display->spiCH,0x0F, (logic) ? 0x01 : 0x00);
|
||||
}
|
||||
|
||||
void max7219_shutdownDiaply(
|
||||
max7219_t *display,
|
||||
uint8_t logic)
|
||||
{
|
||||
spiWriteReg(display->spiCH,0x0C, (logic) ? 0x00 : 0x01);
|
||||
}
|
||||
|
||||
void max7219_setDecodeMode(
|
||||
max7219_t *display,
|
||||
max7219_decodeMode_t dmode)
|
||||
{
|
||||
spiWriteReg(display->spiCH,0x09,(uint8_t) dmode);
|
||||
}
|
||||
|
||||
void max7219_setIntensity(
|
||||
max7219_t *display,
|
||||
uint8_t intensity)
|
||||
{
|
||||
spiWriteReg(display->spiCH, 0x0A, intensity & 0x0F);
|
||||
}
|
||||
|
||||
void max7219_setScanLimit(
|
||||
max7219_t *display,
|
||||
max7219_scanLimit_t slimit)
|
||||
{
|
||||
spiWriteReg(display->spiCH, 0x0B, ((uint8_t) slimit) & 0x0F);
|
||||
}
|
||||
|
||||
void max7219_setAllLEDsOff(
|
||||
max7219_t *display)
|
||||
{
|
||||
uint8_t i;
|
||||
for(i = 0; i < 9; i++) {
|
||||
spiWriteReg(display->spiCH, i, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
void max7219_ledMatrixSetLED(
|
||||
max7219_t *display,
|
||||
uint8_t row,
|
||||
uint8_t col)
|
||||
{
|
||||
|
||||
uint8_t val = 0xAE;
|
||||
|
||||
row = (row & 0x07) + 1;
|
||||
col = 1 << (col & 0x07);
|
||||
|
||||
spiWriteReg(display->spiCH, row,col);
|
||||
}
|
||||
|
||||
void max7219_rawWrite(
|
||||
max7219_t *display,
|
||||
uint8_t reg,
|
||||
uint8_t data)
|
||||
{
|
||||
spiWriteReg(display->spiCH, reg, data);
|
||||
}
|
||||
|
||||
void max7219_printLedMatrix(
|
||||
max7219_t *display,
|
||||
uint8_t matrix[])
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
for(i = 0; i < 8; i ++) {
|
||||
spiWriteReg(display->spiCH, i+1, matrix[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void max7219_ledMatrixUnsetLED(
|
||||
max7219_t *display,
|
||||
uint8_t row,
|
||||
uint8_t col)
|
||||
{
|
||||
row = (row & 0x07) + 1;
|
||||
col = 1 << (col & 0x07);
|
||||
// TODO: find out how to turn off LED
|
||||
spiWriteReg(display->spiCH, row,col+1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
// daysichained matrix
|
||||
typedef struct{
|
||||
spi_ch_t *spiCH;
|
||||
uint8_t nDevices;
|
||||
}max7219_dm_t;
|
||||
|
||||
|
||||
void max7219_dm_write(
|
||||
max7219_dm_t *matrix,
|
||||
uint8_t **data)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
uint8_t j = 0;
|
||||
// TODO: Test it out
|
||||
for(i = 0; i < 8; i++) {
|
||||
pinWrite(matrix->spiCH->pin, 0);
|
||||
for(j = 0; j < matrix->nDevices; j++) {
|
||||
spiTrx8BitPolling(matrix->spiCH->spi, i+1); // reg
|
||||
spiTrx8BitPolling(matrix->spiCH->spi, data[j][i]);
|
||||
}
|
||||
pinWrite(matrix->spiCH->pin, 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -0,0 +1,160 @@
|
||||
/**
|
||||
**************************************************************************************************
|
||||
* @file max7219.h
|
||||
* @author Kerem Yollu & Edwin Koch
|
||||
* @date 25.08.2022
|
||||
* @version 1.0
|
||||
**************************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* **Detailed Description :**
|
||||
*
|
||||
* @todo
|
||||
**************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _MAX7219_H_
|
||||
#define _MAX7219_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "spi.h"
|
||||
#include "pin.h"
|
||||
|
||||
typedef enum{
|
||||
NO_DECODE_DIGIT_7_TO_0 = 0x00,
|
||||
CODE_B_DECODE_ONLY_DIGIT_0 = 0x01,
|
||||
CODE_B_DECODE_ONLY_DIGIT_3_TO_0 = 0x0F,
|
||||
CODE_B_DECOD_DIGIT_7_TO_0 = 0xFF
|
||||
}max7219_decodeMode_t;
|
||||
|
||||
typedef enum{
|
||||
DISPLAY_DIGIT_0 = 0x00,
|
||||
DISPLAY_DIGIT_1_TO_0 = 0x01,
|
||||
DSIPLAX_DIGIT_2_TO_0 = 0x02,
|
||||
DSIPLAX_DIGIT_3_TO_0 = 0x03,
|
||||
DSIPLAX_DIGIT_4_TO_0 = 0x04,
|
||||
DSIPLAX_DIGIT_5_TO_0 = 0x05,
|
||||
DSIPLAX_DIGIT_6_TO_0 = 0x06,
|
||||
DSIPLAX_DIGIT_7_TO_0 = 0x07
|
||||
}max7219_scanLimit_t;
|
||||
|
||||
/**
|
||||
* @brief max7219 matrix class
|
||||
*
|
||||
* The matrix can be ccomposed of only one ore many devices daysichained
|
||||
* together.
|
||||
* @var *spiCH Pointer to spi channel object
|
||||
* @var nDevicesChained Ammount of devices hoocked up together
|
||||
* @var brightness brightness of the matrix
|
||||
* @var buf Array of matrix content. Each n to n + 7 (n can be 0, 8, 16, etc) represents the
|
||||
* content of one individual max7219 device.
|
||||
*/
|
||||
typedef struct{
|
||||
spi_ch_t *spiCH;
|
||||
uint8_t nDevicesChained;
|
||||
uint8_t brightness;
|
||||
uint8_t buf[];
|
||||
}max7219_mx_t;
|
||||
|
||||
void max7219_t_mx_init(
|
||||
max7219_mx_t *matrix,
|
||||
spi_ch_t *spiChannel,
|
||||
uint8_t *pBuf,
|
||||
uint8_t bufLen);
|
||||
|
||||
void max7219_mx_setPixel(
|
||||
max7219_mx_t *matrix,
|
||||
uint8_t row,
|
||||
uint8_t col,
|
||||
uint8_t logic);
|
||||
|
||||
void max7219_mx_print(
|
||||
max7219_mx_t *matrix,
|
||||
char *text,
|
||||
uint8_t len);
|
||||
|
||||
void max7219_mx_show(
|
||||
max7219_mx_t *matrix);
|
||||
|
||||
void max7219_mx_shutdown(
|
||||
max7219_mx_t *matrix);
|
||||
|
||||
void max7219_mx_test(
|
||||
max7219_mx_t *matrix);
|
||||
|
||||
void max7219_mx_mapMatrix(
|
||||
max7219_mx_t *matrix,
|
||||
uint8_t *map);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
void max7219_init(
|
||||
max7219_t *display,
|
||||
spi_ch_t *spi_ch);
|
||||
|
||||
void max7219_testDisplay(
|
||||
max7219_t *display,
|
||||
uint8_t logic);
|
||||
|
||||
void max7219_shutdownDiaply(
|
||||
max7219_t *display,
|
||||
uint8_t logic);
|
||||
|
||||
void max7219_setDecodeMode(
|
||||
max7219_t *display,
|
||||
max7219_decodeMode_t dmode);
|
||||
|
||||
void max7219_setIntensity(
|
||||
max7219_t *display,
|
||||
uint8_t intensity);
|
||||
|
||||
void max7219_setScanLimit(
|
||||
max7219_t *display,
|
||||
max7219_scanLimit_t slimit);
|
||||
|
||||
void max7219_setAllLEDsOff(
|
||||
max7219_t *display);
|
||||
|
||||
void max7219_ledMatrixSetLED(
|
||||
max7219_t *display,
|
||||
uint8_t row,
|
||||
uint8_t col);
|
||||
|
||||
void max7219_rawWrite(
|
||||
max7219_t *display,
|
||||
uint8_t reg,
|
||||
uint8_t data);
|
||||
|
||||
void max7219_printLedMatrix(
|
||||
max7219_t *display,
|
||||
uint8_t matrix[]);
|
||||
|
||||
void max7219_ledMatrixUnsetLED(
|
||||
max7219_t *display,
|
||||
uint8_t row,
|
||||
uint8_t col);
|
||||
#if 0
|
||||
// daysichained matrix
|
||||
typedef struct{
|
||||
spi_ch_t *spiCH;
|
||||
uint8_t nDevices;
|
||||
}max7219_dm_t;
|
||||
|
||||
|
||||
void max7219_dm_write(
|
||||
max7219_dm_t *matrix,
|
||||
uint8_t **data);
|
||||
#endif
|
||||
*/
|
||||
#ifdef _cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _MAX7219_H_
|
Binary file not shown.
@ -0,0 +1,287 @@
|
||||
/*********************************************************************
|
||||
SSD1306 I2C Library for Raspberry Pi.
|
||||
Based on Adafruit SSD1306 Arduino library. Some functions came from Adafruit GFX lib
|
||||
|
||||
Modified by Ilia Penev
|
||||
Tested on Raspberry Pi 2 with 0.96 Yellow/Blue OLED
|
||||
*********************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
This is a library for our Monochrome OLEDs based on SSD1306 drivers
|
||||
|
||||
Pick one up today in the adafruit shop!
|
||||
------> http://www.adafruit.com/category/63_98
|
||||
|
||||
These displays use SPI to communicate, 4 or 5 pins are required to
|
||||
interface
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
BSD license, check license.txt for more information
|
||||
All text above, and the splash screen below must be included in any redistribution
|
||||
*********************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ssd1306_i2c.h"
|
||||
#include "oled_fonts.h"
|
||||
#include "lcd_oled.h"
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#define rotation 0
|
||||
|
||||
int8_t cursor_y = 0;
|
||||
int8_t cursor_x = 0;
|
||||
|
||||
int16_t i2cd;
|
||||
|
||||
#define ssd1306_swap(a, b) { int16_t t = a; a = b; b = t; }
|
||||
|
||||
//Section : 10.1.12 Set Display ON/OFF (AEh/AFh) | Page 37
|
||||
void ssd1306_i2c_set_display_off(i2c_t *i2c_dev)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_DISPLAYOFF);
|
||||
}
|
||||
|
||||
//Section : 10.1.12 Set Display ON/OFF (AEh/AFh) | Page 37
|
||||
void ssd1306_i2c_set_display_on(i2c_t *i2c_dev)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_DISPLAYON);
|
||||
}
|
||||
|
||||
// TODO: Find a ferq Calculator
|
||||
// Section : 10.1.16 Set Display Clock Divide Ratio/ Oscillator Frequency (D5h) | Page : 40
|
||||
void ssd1306_i2c_set_display_clkDiv_oscFreq(i2c_t *i2c_dev, uint8_t clockDivider, uint8_t oscillatorFreq)
|
||||
{
|
||||
|
||||
uint8_t value = 0;
|
||||
|
||||
if(oscillatorFreq <= 15)
|
||||
{
|
||||
if(clockDivider <= 16)
|
||||
{
|
||||
value = (oscillatorFreq << 4) | clockDivider;
|
||||
}
|
||||
}
|
||||
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
|
||||
ssd1306_i2c_send_command(i2c_dev,value); // the suggested ratio 0x80
|
||||
}
|
||||
|
||||
// Section : 10.1.11 Set Multiplex Ratio (A8h) | Page : 37
|
||||
void ssd1306_i2c_set_multiplex_ratio(i2c_t *i2c_dev, uint8_t ratio)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETMULTIPLEX); // 0xA8
|
||||
ssd1306_i2c_send_command(i2c_dev,ratio);
|
||||
}
|
||||
|
||||
// Section : 10.1.15 Set Display Offset (D3h) | Page : 37
|
||||
void ssd1306_i2c_set_display_offset(i2c_t *i2c_dev, uint8_t offset)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETDISPLAYOFFSET); // 0xD3
|
||||
ssd1306_i2c_send_command(i2c_dev,offset);
|
||||
}
|
||||
// Section : 10.1.13 Set Page Start Address for Page Addressing Mode (B0h~B7h) | Page : 37
|
||||
void ssd1306_i2c_set_display_start_line(i2c_t *i2c_dev, uint8_t start)
|
||||
{
|
||||
if(start <= 7)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETSTARTLINE | start);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : Some things are not clear What does 0x10 do ?
|
||||
// Section : 2.1 Command Table for Charge Bump Setting | Page : 60
|
||||
void ssd1306_i2c_set_chage_pump(i2c_t *i2c_dev, uint8_t voltageSource)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_CHARGEPUMP); // 0x8D
|
||||
if (voltageSource == SSD1306_EXTERNALVCC) {
|
||||
ssd1306_i2c_send_command(i2c_dev,0x10);
|
||||
} else {
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_ENABLE_CHAGE_PUMP);
|
||||
}
|
||||
}
|
||||
|
||||
// Section :10.1.3 Set Memory Addressing Mode (20h) | Page : 34
|
||||
void ssd1306_i2c_set_memory_addressing_mode(i2c_t *i2c_dev, uint8_t mode)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_MEMORYMODE);
|
||||
ssd1306_i2c_send_command(i2c_dev,mode);
|
||||
}
|
||||
|
||||
// TODO : Not very clear what this functionality does :S
|
||||
// Section : 10.1.8 Set Segment Re-map (A0h/A1h)
|
||||
void ssd1306_i2c_set_segment_remap(i2c_t *i2c_dev, uint8_t enable)
|
||||
{
|
||||
if(enable)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_SEGREMAP | 0x1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_SEGREMAP | 0x0);
|
||||
}
|
||||
}
|
||||
// Section : 10.1.14 Set COM Output Scan Direction (C0h/C8h) | Page 37
|
||||
void ssd1306_i2c_set_com_scan_direction(i2c_t *i2c_dev, uint8_t incremental)
|
||||
{
|
||||
if(incremental)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_COMSCANINC);
|
||||
}
|
||||
else
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_COMSCANDEC);
|
||||
}
|
||||
}
|
||||
|
||||
// Section : 10.1.18 Set COM Pins Hardware Configuration (DAh) | Page : 40
|
||||
void ssd1306_i2c_set_com_pins(i2c_t *i2c_dev, uint8_t alignment)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETCOMPINS);
|
||||
ssd1306_i2c_send_command(i2c_dev,alignment);
|
||||
}
|
||||
|
||||
void ssd1306_i2c_set_contrast(i2c_t *i2c_dev, uint8_t contrast)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETCONTRAST); // 0x81
|
||||
ssd1306_i2c_send_command(i2c_dev,contrast);
|
||||
}
|
||||
|
||||
void ssd1306_i2c_set_prechage_period(i2c_t *i2c_dev, uint8_t period)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETPRECHARGE); // 0xd9
|
||||
ssd1306_i2c_send_command(i2c_dev,period);
|
||||
}
|
||||
|
||||
void ssd1306_i2c_set_com_deselect_level(i2c_t *i2c_dev, uint8_t voltageLevel)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETVCOMDETECT); // 0xDB
|
||||
ssd1306_i2c_send_command(i2c_dev,voltageLevel);
|
||||
}
|
||||
|
||||
void ssd1306_i2c_set_display_entire_on(i2c_t *i2c_dev, uint8_t resumeOrForce)
|
||||
{
|
||||
if(resumeOrForce == SSD1306_DISPLAYALLON_RESUME)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_DISPLAYALLON_RESUME); // 0xA4
|
||||
}
|
||||
else
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_DISPLAYALLON); // 0xA4
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ssd1306_i2c_set_display_invert_pixel(i2c_t *i2c_dev, uint8_t inverted)
|
||||
{
|
||||
if(inverted)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_INVERTDISPLAY); // 0xA6
|
||||
}
|
||||
else
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_NORMALDISPLAY); // 0xA6
|
||||
}
|
||||
}
|
||||
|
||||
void ssd1306_i2c_set_scroll(i2c_t *i2c_dev, uint8_t onOff)
|
||||
{
|
||||
if(onOff)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_DEACTIVATE_SCROLL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ssd1306_i2c_send_command(i2c_t *i2c_dev,uint8_t c)
|
||||
{
|
||||
// I2C
|
||||
uint8_t control = 0x00; // Co = 0, D/C = 0
|
||||
uint8_t i2cDataLenght = 1; // Co = 0, D/C = 0
|
||||
uint16_t address = SSD1306_I2C_ADDRESS; // Co = 0, D/C = 0
|
||||
i2c_write(i2c_dev, &address, &control, &c, &i2cDataLenght);
|
||||
}
|
||||
|
||||
|
||||
// startscrollright
|
||||
// Activate a right handed scroll for rows start through stop
|
||||
// Hint, the display is 16 rows tall. To scroll the whole display, run:
|
||||
// ssd1306_scrollright(0x00, 0x0F)
|
||||
void ssd1306_startscrollright(i2c_t *i2c_dev, uint16_t start, uint16_t stop)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_RIGHT_HORIZONTAL_SCROLL);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X00);
|
||||
ssd1306_i2c_send_command(i2c_dev,start);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X00);
|
||||
ssd1306_i2c_send_command(i2c_dev,stop);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X00);
|
||||
ssd1306_i2c_send_command(i2c_dev,0XFF);
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
|
||||
}
|
||||
|
||||
// startscrollleft
|
||||
// Activate a right handed scroll for rows start through stop
|
||||
// Hint, the display is 16 rows tall. To scroll the whole display, run:
|
||||
// ssd1306_scrollright(0x00, 0x0F)
|
||||
void ssd1306_startscrollleft(i2c_t *i2c_dev,uint16_t start, uint16_t stop)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_LEFT_HORIZONTAL_SCROLL);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X00);
|
||||
ssd1306_i2c_send_command(i2c_dev,start);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X00);
|
||||
ssd1306_i2c_send_command(i2c_dev,stop);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X00);
|
||||
ssd1306_i2c_send_command(i2c_dev,0XFF);
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
|
||||
}
|
||||
|
||||
// startscrolldiagright
|
||||
// Activate a diagonal scroll for rows start through stop
|
||||
// Hint, the display is 16 rows tall. To scroll the whole display, run:
|
||||
// ssd1306_scrollright(0x00, 0x0F)
|
||||
void ssd1306_startscrolldiagright(i2c_t *i2c_dev, uint16_t start, uint16_t stop)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_SET_VERTICAL_SCROLL_AREA);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X00);
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_LCDHEIGHT);
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X00);
|
||||
ssd1306_i2c_send_command(i2c_dev,start);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X00);
|
||||
ssd1306_i2c_send_command(i2c_dev,stop);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X01);
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
|
||||
}
|
||||
|
||||
// startscrolldiagleft
|
||||
// Activate a diagonal scroll for rows start through stop
|
||||
// Hint, the display is 16 rows tall. To scroll the whole display, run:
|
||||
// ssd1306_scrollright(0x00, 0x0F)
|
||||
void ssd1306_startscrolldiagleft(i2c_t *i2c_dev, uint16_t start, uint16_t stop)
|
||||
{
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_SET_VERTICAL_SCROLL_AREA);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X00);
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_LCDHEIGHT);
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X00);
|
||||
ssd1306_i2c_send_command(i2c_dev,start);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X00);
|
||||
ssd1306_i2c_send_command(i2c_dev,stop);
|
||||
ssd1306_i2c_send_command(i2c_dev,0X01);
|
||||
ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,173 @@
|
||||
/*********************************************************************
|
||||
SSD1306 I2C Library for Raspberry Pi.
|
||||
Based on Adafruit SSD1306 Arduino library. Some functions came from Adafruit GFX lib.
|
||||
|
||||
Modified by Ilia Penev
|
||||
Tested on Raspberry Pi 2 with 0.96 Yellow/Blue OLED
|
||||
*********************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
This is a library for our Monochrome OLEDs based on SSD1306 drivers
|
||||
|
||||
Pick one up today in the adafruit shop!
|
||||
------> http://www.adafruit.com/category/63_98
|
||||
|
||||
These displays use SPI to communicate, 4 or 5 pins are required to
|
||||
interface
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
BSD license, check license.txt for more information
|
||||
All text above, and the splash screen must be included in any redistribution
|
||||
*********************************************************************/
|
||||
#ifndef SSD1306_I2C_H_
|
||||
#define SSD1306_I2C_H_
|
||||
|
||||
#include "i2c.h"
|
||||
|
||||
#define BLACK 0
|
||||
#define WHITE 1
|
||||
#define INVERSE 2
|
||||
|
||||
#define SSD1306_I2C_ADDRESS 0x3C // 011110+SA0+RW - 0x3C or 0x3D
|
||||
// Address for 128x32 is 0x3C
|
||||
// Address for 128x64 is 0x3D (default) or 0x3C (if SA0 is grounded)
|
||||
|
||||
/*=========================================================================
|
||||
SSD1306 Displays
|
||||
-----------------------------------------------------------------------
|
||||
The driver is used in multiple displays (128x64, 128x32, etc.).
|
||||
Select the appropriate display below to create an appropriately
|
||||
sized framebuffer, etc.
|
||||
|
||||
SSD1306_128_64 128x64 pixel display
|
||||
|
||||
SSD1306_128_32 128x32 pixel display
|
||||
|
||||
SSD1306_96_16
|
||||
|
||||
-----------------------------------------------------------------------*/
|
||||
#define SSD1306_128_64
|
||||
// #define SSD1306_128_32
|
||||
// #define SSD1306_96_16
|
||||
/*=========================================================================*/
|
||||
|
||||
#if defined SSD1306_128_32
|
||||
#define WIDTH 128
|
||||
#define HEIGHT 32
|
||||
#endif
|
||||
|
||||
#if defined SSD1306_128_64
|
||||
#define WIDTH 128
|
||||
#define HEIGHT 64
|
||||
#endif
|
||||
|
||||
#if defined SSD1306_96_16
|
||||
#define WIDTH 96
|
||||
#define HEIGHT 16
|
||||
#endif
|
||||
|
||||
#if defined SSD1306_128_64 && defined SSD1306_128_32
|
||||
#error "Only one SSD1306 display can be specified at once in SSD1306.h"
|
||||
#endif
|
||||
#if !defined SSD1306_128_64 && !defined SSD1306_128_32 && !defined SSD1306_96_16
|
||||
#error "At least one SSD1306 display must be specified in SSD1306.h"
|
||||
#endif
|
||||
|
||||
#if defined SSD1306_128_64
|
||||
#define SSD1306_LCDWIDTH 128
|
||||
#define SSD1306_LCDHEIGHT 64
|
||||
#endif
|
||||
#if defined SSD1306_128_32
|
||||
#define SSD1306_LCDWIDTH 128
|
||||
#define SSD1306_LCDHEIGHT 32
|
||||
#endif
|
||||
#if defined SSD1306_96_16
|
||||
#define SSD1306_LCDWIDTH 96
|
||||
#define SSD1306_LCDHEIGHT 16
|
||||
#endif
|
||||
|
||||
#define SSD1306_SETCONTRAST 0x81
|
||||
#define SSD1306_DISPLAYALLON_RESUME 0xA4
|
||||
#define SSD1306_DISPLAYALLON 0xA5
|
||||
#define SSD1306_NORMALDISPLAY 0xA6
|
||||
#define SSD1306_INVERTDISPLAY 0xA7
|
||||
#define SSD1306_DISPLAYOFF 0xAE
|
||||
#define SSD1306_DISPLAYON 0xAF
|
||||
|
||||
#define SSD1306_SETDISPLAYOFFSET 0xD3
|
||||
#define SSD1306_SETCOMPINS 0xDA
|
||||
|
||||
#define SSD1306_SETVCOMDETECT 0xDB
|
||||
|
||||
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
|
||||
#define SSD1306_SETPRECHARGE 0xD9
|
||||
|
||||
#define SSD1306_SETMULTIPLEX 0xA8
|
||||
|
||||
#define SSD1306_SETLOWCOLUMN 0x00
|
||||
#define SSD1306_SETHIGHCOLUMN 0x10
|
||||
|
||||
#define SSD1306_SETSTARTLINE 0x40
|
||||
|
||||
#define SSD1306_MEMORYMODE 0x20
|
||||
#define SSD1306_MEMORY_MODE_PAGE 0x04
|
||||
#define SSD1306_MEMORY_MODE_HORIZONTAL 0x00
|
||||
#define SSD1306_MEMORY_MODE_VERTICAL 0x01
|
||||
|
||||
#define SSD1306_COLUMNADDR 0x21
|
||||
#define SSD1306_PAGEADDR 0x22
|
||||
|
||||
#define SSD1306_COMSCANINC 0xC0
|
||||
#define SSD1306_COMSCANDEC 0xC8
|
||||
#define SSD1306_COM_SEQ_LR_REMAP_OFF 0x02
|
||||
#define SSD1306_COM_SEQ_LR_REMAP_ON 0x12
|
||||
#define SSD1306_COM_ALT_LR_REMAP_OFF 0x0A
|
||||
#define SSD1306_COM_ALT_LR_REMAP_ON 0x1A
|
||||
|
||||
#define SSD1306_SEGREMAP 0xA0
|
||||
|
||||
#define SSD1306_CHARGEPUMP 0x8D
|
||||
#define SSD1306_ENABLE_CHAGE_PUMP 0x14
|
||||
#define SSD1306_EXTERNALVCC 0x1
|
||||
#define SSD1306_SWITCHCAPVCC 0x2
|
||||
|
||||
|
||||
|
||||
// Scrolling #defines
|
||||
#define SSD1306_ACTIVATE_SCROLL 0x2F
|
||||
#define SSD1306_DEACTIVATE_SCROLL 0x2E
|
||||
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
|
||||
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
|
||||
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
|
||||
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
|
||||
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
|
||||
|
||||
void ssd1306_startscrolldiagright(i2c_t *i2c_dev, uint16_t start, uint16_t stop);
|
||||
void ssd1306_startscrolldiagleft(i2c_t *i2c_dev, uint16_t start, uint16_t stop);
|
||||
void ssd1306_stopscroll(i2c_t *i2c_dev);
|
||||
|
||||
void ssd1306_i2c_send_command(i2c_t *i2c_dev,uint8_t c);
|
||||
void ssd1306_i2c_set_display_off(i2c_t *i2c_dev);
|
||||
void ssd1306_i2c_set_display_on(i2c_t *i2c_dev);
|
||||
void ssd1306_i2c_set_display_clkDiv_oscFreq(i2c_t *i2c_dev, uint8_t clockDivider, uint8_t oscillatorFreq);
|
||||
void ssd1306_i2c_set_multiplex_ratio(i2c_t *i2c_dev, uint8_t ratio);
|
||||
void ssd1306_i2c_set_display_offset(i2c_t *i2c_dev, uint8_t offset);
|
||||
void ssd1306_i2c_set_display_start_line(i2c_t *i2c_dev, uint8_t start);
|
||||
void ssd1306_i2c_set_chage_pump(i2c_t *i2c_dev, uint8_t voltageSource);
|
||||
void ssd1306_i2c_set_memory_addressing_mode(i2c_t *i2c_dev, uint8_t mode);
|
||||
void ssd1306_i2c_set_segment_remap(i2c_t *i2c_dev, uint8_t enable);
|
||||
void ssd1306_i2c_set_com_scan_direction(i2c_t *i2c_dev, uint8_t incremental);
|
||||
void ssd1306_i2c_set_com_pins(i2c_t *i2c_dev, uint8_t alignment);
|
||||
void ssd1306_i2c_set_contrast(i2c_t *i2c_dev, uint8_t contrast);
|
||||
void ssd1306_i2c_set_dimm(i2c_t *i2c_dev, uint8_t dimm);
|
||||
void ssd1306_i2c_set_prechage_period(i2c_t *i2c_dev, uint8_t period);
|
||||
void ssd1306_i2c_set_com_deselect_level(i2c_t *i2c_dev, uint8_t voltageLevel);
|
||||
void ssd1306_i2c_set_display_entire_on(i2c_t *i2c_dev, uint8_t resumeOrForce);
|
||||
void ssd1306_i2c_set_display_invert_pixel(i2c_t *i2c_dev, uint8_t inverted);
|
||||
void ssd1306_i2c_set_scroll(i2c_t *i2c_dev, uint8_t onOff);
|
||||
|
||||
#endif /* _SSD1306_I2C_H_ */
|
@ -0,0 +1,150 @@
|
||||
####################################################################################################
|
||||
# DIRECTORY CHECKS
|
||||
####################################################################################################
|
||||
function(checkDirectory _directory)
|
||||
if(EXISTS ${_directory})
|
||||
else()
|
||||
errorDirNotFound("${_directory}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
####################################################################################################
|
||||
# HEADER MANAGEMENT
|
||||
####################################################################################################
|
||||
# This function goes an searches for directories containing header files and return the corresponding directory.
|
||||
function(createHeaderDirList _directory _list _headersList)
|
||||
set(_newheaderDirList)
|
||||
foreach(DIR IN LISTS _list)
|
||||
checkDirectory("${_directory}/${DIR}")
|
||||
list(APPEND _newheaderDirList ${_directory}/${DIR})
|
||||
message("${BoldMagenta} |-> Added : ${_directory}/${DIR}")
|
||||
endforeach()
|
||||
message("${ColourReset}")
|
||||
set(${_headersList} ${_newheaderDirList} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
# This function searches for the given header file name (_alias) if it has benn included
|
||||
# If it finds it it retursn the directory where the header is Located
|
||||
# If it doesn't find a header it generates a fatal error
|
||||
function(checkIfHeaderFileIncluded _alias _retDir)
|
||||
set(_headerFound FALSE)
|
||||
set(_headerDirFound)
|
||||
foreach(_headerDir IN LISTS COMMON_HEADERS)
|
||||
if(EXISTS ${_headerDir}/${alias}.h)
|
||||
set(_headerFound TRUE)
|
||||
set(_headerDirFound ${_headerDir})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(_headerFound)
|
||||
set(${_retDir} ${_headerDirFound}/${alias}.h PARENT_SCOPE)
|
||||
else()
|
||||
errorHFileNotFound(${_headerDirFound} ${_alias})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# This function searches for the given header file name (_alias) if it has benn included
|
||||
# If it finds it it retursn the directory where the header is Located
|
||||
# If it doesn't find a header it returns a Non Found Message
|
||||
function(searchHeaderFile _alias _retDir)
|
||||
set(_headerFound FALSE)
|
||||
set(_headerDirFound)
|
||||
foreach(_headerDir IN LISTS COMMON_HEADERS)
|
||||
if(EXISTS ${_headerDir}/${_alias}.h)
|
||||
set(_headerFound TRUE)
|
||||
set(_headerDirFound ${_headerDir})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(_headerFound)
|
||||
set(${_retDir} ${_headerDirFound}/${_alias}.h PARENT_SCOPE)
|
||||
else()
|
||||
set(${_retDir} "No corresponding header << ${_alias}.h >> found " PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# SUBMODULE MANAGEMENT
|
||||
####################################################################################################
|
||||
function(makeSubmodules _directory _aliasList _submoduleList)
|
||||
set(_newSubmoduleList)
|
||||
set(_headerLoc)
|
||||
#For each alias of element present on the list that has been given as argument
|
||||
foreach(alias IN LISTS _aliasList)
|
||||
|
||||
checkDirectory("${_directory}/${alias}") # Does the directory exists (If not fatal error)
|
||||
|
||||
#Does the given element has an implmenetation for a CSL
|
||||
if(EXISTS ${CSL_SOURCES_DIR}/imp_${alias}.${PL}) #If yes
|
||||
message("${BoldCyan} |-> Target Found : ${alias} ${BoldYellow} ")
|
||||
|
||||
checkIfHeaderFileIncluded("${alias}" "_headerLoc") #Every Implementation has to have a header (if not Fatal Error)
|
||||
|
||||
#Does the given element has an predefined standart usage library
|
||||
if(EXISTS ${_directory}/${alias}/${alias}.${PL}) # If yes then add this to the compiling list
|
||||
message(" |-> Def Header : ${_headerLoc}")
|
||||
message(" |-> Lib Source : ${_directory}/${alias}/${alias}.${PL} ")
|
||||
message(" |-> Imp source : ${CSL_SOURCES_DIR}/imp_${alias}.${PL}")
|
||||
|
||||
add_library(${alias}_submodule ${_directory}/${alias}/${alias}.${PL} ${CSL_SOURCES_DIR}/imp_${alias}.${PL})
|
||||
else() # If No than just compile the implmentation source
|
||||
message(" |-> Def Header : ${_headerLoc}")
|
||||
message(" |-> Imp source : ${CSL_SOURCES_DIR}/imp_${alias}.${PL}")
|
||||
|
||||
add_library(${alias}_submodule ${CSL_SOURCES_DIR}/imp_${alias}.${PL})
|
||||
endif()
|
||||
|
||||
message(" |-> Name : sub::${alias}")
|
||||
|
||||
target_compile_options(${alias}_submodule PRIVATE ${MAIN_FLAGS})
|
||||
target_compile_definitions(${alias}_submodule PRIVATE ${MAIN_DEFS})
|
||||
target_include_directories(${alias}_submodule PUBLIC ${COMMON_HEADERS})
|
||||
add_library(sub::${alias} ALIAS ${alias}_submodule)
|
||||
|
||||
#Append the internal submodule list with the newly compiled element
|
||||
list(APPEND _newSubmoduleList sub::${alias})
|
||||
|
||||
else() # Else, when the element has no implmentation for a CSL
|
||||
#If the element has an source file
|
||||
if(EXISTS ${_directory}/${alias}/${alias}.${PL})
|
||||
searchHeaderFile("${alias}" "_headerLoc") #Searches if there is an Header (if not it will not generate any error)
|
||||
message("${BoldCyan} |-> Target Found : ${alias} ${BoldYellow} ")
|
||||
message(" |-> Header : ${_headerLoc}")
|
||||
message(" |-> Source : ${_directory}/${alias}/${alias}.${PL}")
|
||||
message(" |-> Name : sub::${alias}")
|
||||
|
||||
add_library(${alias}_submodule ${_directory}/${alias}/${alias}.${PL})
|
||||
target_compile_options(${alias}_submodule PRIVATE ${MAIN_FLAGS})
|
||||
target_compile_definitions(${alias}_submodule PRIVATE ${MAIN_DEFS})
|
||||
target_include_directories(${alias}_submodule PUBLIC ${COMMON_HEADERS})
|
||||
add_library(sub::${alias} ALIAS ${alias}_submodule)
|
||||
|
||||
#Append the internal submodule list with the newly compiled element
|
||||
list(APPEND _newSubmoduleList sub::${alias})
|
||||
|
||||
else() # When the element has no source file and is only a header.
|
||||
message("${BoldMagenta} |-> No Source file for target : ${alias}")
|
||||
message(" |-> Only headers will be added")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
endforeach()
|
||||
|
||||
message("${ColourReset}")
|
||||
|
||||
#New submodule list with the names of the compiled elements
|
||||
set(${_submoduleList} ${_newSubmoduleList} PARENT_SCOPE)
|
||||
|
||||
endfunction()
|
||||
|
||||
####################################################################################################
|
||||
# PRINT FUNCTIONS
|
||||
####################################################################################################
|
||||
function(printList _txt _list)
|
||||
foreach(X IN LISTS _list)
|
||||
message("${_txt}${X}")
|
||||
endforeach()
|
||||
endfunction()
|
@ -0,0 +1,47 @@
|
||||
function(createHeaderDirListProject _list _headersList)
|
||||
foreach(DIR IN LISTS _list)
|
||||
checkDirectory("${PROJECT_DIR}/${DIR}")
|
||||
list(APPEND _newheaderDirList ${PROJECT_DIR}/${DIR})
|
||||
message("${BoldMagenta} |-> Added : ${PROJECT_DIR}/${DIR}")
|
||||
endforeach()
|
||||
message("${ColourReset}")
|
||||
set(${_headersList} ${_newheaderDirList} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
####################################################################################################
|
||||
# SUBMODULE MANAGEMENT
|
||||
####################################################################################################
|
||||
function(makeSubmodulesProject _directoryList _aliasList _submoduleList)
|
||||
set(_newSubmoduleList)
|
||||
set(_subName)
|
||||
set(_headerLoc)
|
||||
|
||||
foreach(_dir IN LISTS _directoryList)
|
||||
checkDirectory("${PROJECT_DIR}/${_dir}") # Does the directory exists (If not fatal error)
|
||||
#For each alias of element present on the list that have been given as argument
|
||||
|
||||
foreach(_name IN LISTS _aliasList)
|
||||
if(EXISTS ${PROJECT_DIR}/${_dir}/${_name})
|
||||
string(REPLACE ".c" "" _subName ${_name})
|
||||
searchHeaderFile("${_subName}" "_headerLoc") #Searches if there is an Header (if not it will not generate any error)
|
||||
message("${BoldGreen} |-> Directory Found : ${PROJECT_DIR}/${_dir}")
|
||||
message("${BoldCyan} |-> Target Found : ${_subName} ${BoldYellow} ")
|
||||
message(" |-> Header : ${_headerLoc}")
|
||||
message(" |-> Source : ${PROJECT_DIR}/${_dir}/${_name}")
|
||||
message(" |-> Name : sub::${_subName}")
|
||||
|
||||
add_library(${_subName}_submodule ${PROJECT_DIR}/${_dir}/${_subName})
|
||||
target_compile_options(${_subName}_submodule PRIVATE ${MAIN_FLAGS})
|
||||
target_compile_definitions(${_subName}_submodule PRIVATE ${MAIN_DEFS})
|
||||
target_include_directories(${_subName}_submodule PUBLIC ${COMMON_HEADERS})
|
||||
add_library(sub::${_subName} ALIAS ${_subName}_submodule)
|
||||
|
||||
#Append the internal submodule list with the newly compiled element
|
||||
list(APPEND _newSubmoduleList sub::${_subName})
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
message("${ColourReset}")
|
||||
#New submodule list with the names of the compiled elements
|
||||
set(${_submoduleList} ${_newSubmoduleList} PARENT_SCOPE)
|
||||
endfunction()
|
@ -1,4 +1,6 @@
|
||||
|
||||
####################################################################################################
|
||||
# CMAKE Colors
|
||||
####################################################################################################
|
||||
if(NOT WIN32)
|
||||
string(ASCII 27 Esc)
|
||||
set(ColourReset "${Esc}[m")
|
@ -0,0 +1,29 @@
|
||||
####################################################################################################
|
||||
# DOXYGEN
|
||||
####################################################################################################
|
||||
|
||||
function(generateDoxygen)
|
||||
if(OUTPUT_DOXYGEN)
|
||||
find_package(Doxygen)
|
||||
if (DOXYGEN_FOUND)
|
||||
set(DOXYGEN_IN ${CMAKE_CORE_DIR}/doxyfile.in)
|
||||
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/doxyfile)
|
||||
message("${Green}")
|
||||
message("+-------------------------------+")
|
||||
message("Generating Doxygen output")
|
||||
message("+-------------------------------+")
|
||||
message("${ColourReset}")
|
||||
|
||||
# request to configure the file
|
||||
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
|
||||
# note the option ALL which allows to build the docs together with the application
|
||||
add_custom_target( doc_doxygen ALL
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
|
||||
WORKING_DIRECTORY ${DOXYGEN_OUTPUT_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen"
|
||||
VERBATIM )
|
||||
else (DOXYGEN_FOUND)
|
||||
message("Doxygen need to be installed to generate the doxygen documentation")
|
||||
endif (DOXYGEN_FOUND)
|
||||
endif(OUTPUT_DOXYGEN)
|
||||
endfunction()
|
@ -0,0 +1,67 @@
|
||||
function(errorDetected)
|
||||
message("${Red}\n")
|
||||
message("#########################################")
|
||||
message("#\t@@@@ @@@ @@@ @@ @@@ \t#")
|
||||
message("#\t@ @ @ @ @ @ @ @ @ \t#")
|
||||
message("#\t@@@ @@@ @@@ @ @ @@@ \t#")
|
||||
message("#\t@ @ @ @ @ @ @ @ @ \t#")
|
||||
message("#\t@@@@ @ @ @ @ @@ @ @ \t#")
|
||||
message("#########################################")
|
||||
message("#\tAN ERROR HAS OCCURED\t\t#")
|
||||
message("#########################################")
|
||||
endfunction()
|
||||
|
||||
function(errorOut)
|
||||
message("#########################################\n\n")
|
||||
endfunction()
|
||||
|
||||
function(errorDirNotFound _searchedDir)
|
||||
errorDetected()
|
||||
message(" |-->GIVEN DIRECTORY NOT FOUND")
|
||||
message(" |-> Given dir : ${DIR}")
|
||||
message("!!! Possible Reasons !!!")
|
||||
message(" |--> Did you give corect path in ${PROJECT_CONFIG_FILE} ??")
|
||||
message(" |-> The declaration for HEADERS should look like :")
|
||||
message(" |-> list(APPEND PROJECT_HEADERS_DIR \$\{PROJECT_DIR\}/path_to_header_directory")
|
||||
message(" |-> \$\{PROJECT_DIR\} = ${PROJECT_DIR}")
|
||||
message(" |-> The declaration for SOURCES should look like :")
|
||||
message(" |-> list(APPEND PROJECT_SOURCES_DIR \$\{PROJECT_DIR\}/path_to_source_directory")
|
||||
message(" |-> \$\{PROJECT_DIR\} = ${PROJECT_DIR}")
|
||||
message("If A Directory has source and header files, it should be declared 2 times accordingly")
|
||||
message(" |--> Once as HEADER location")
|
||||
message(" |--> Once as SOURCES location")
|
||||
message("\nFor more information please refer to : ${CMAKE_SOURCE_DIR}/README.md\n")
|
||||
errorOut()
|
||||
message(FATAL_ERROR "Directory ${DIR} : NOT FOUND")
|
||||
endfunction()
|
||||
|
||||
function(errorHFileNotFound _directory _alias)
|
||||
errorDetected()
|
||||
message("The header file <<${_alias}.h>> was not found")
|
||||
message(" |--> Given directory is : ${_directory}/${_alias}")
|
||||
message(" |--> Given Header file path : ${_directory}/${_alias}/${_alias}.h")
|
||||
message("!!! Possible Reasons !!!")
|
||||
message(" |--> Did you name the module correctly in ${_directory}/CMakeLists.txt ??")
|
||||
message(" |-> The module name should be : ")
|
||||
message(" |-> The same as the the folder name")
|
||||
message(" |-> The same as the the source name")
|
||||
message(" |-> The same as the the header name")
|
||||
message("\nFor more information please refer to : ${_directory}/README.md\n")
|
||||
errorOut()
|
||||
message(FATAL_ERROR "\n NO Header file : <<${_alias}.h>> was found ### COMPILATION ABORTED ###\n")
|
||||
endfunction()
|
||||
|
||||
function(errorHDirNotFound _dir _alias)
|
||||
errorDetected()
|
||||
message("The file <<${_alias}>> was not found")
|
||||
message(" |--> Given directory is : ${_directory}/${_alias}")
|
||||
message("!!! Possible Reasons !!!")
|
||||
message(" |--> Did you name the module correctly in ${_directory}/CMakeLists.txt ??")
|
||||
message(" |-> The module name should be : ")
|
||||
message(" |-> The same as the the folder name")
|
||||
message(" |-> The same as the the source name")
|
||||
message(" |-> The same as the the header name")
|
||||
message("\nFor more information please refer to : ${_directory}/README.md\n")
|
||||
errorOut()
|
||||
message(FATAL_ERROR "\nNO Directory : <<${_directory}/${_alias}>> was found ### COMPILATION ABORTED ###\n")
|
||||
endfunction()
|
@ -0,0 +1,28 @@
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def eraseFirmware(TARGET_DEVICE):
|
||||
if sys.platform == 'linux':
|
||||
print('TODO')
|
||||
if sys.platform == 'win32':
|
||||
subprocess.Popen("STM32_Programmer_CLI.exe -c port=SWD -fwdelete")
|
||||
|
||||
def downloadFirmware(TARGET_DEVICE):
|
||||
print('TODO')
|
||||
|
||||
def flash(TARGET_DEVICE, buildDirectory):
|
||||
# find out what platform the build is done (e.g. linux, win32, etc.)
|
||||
|
||||
if sys.platform == 'linux':
|
||||
os.system('st-flash write' + TARGET_DEVICE + '.bin 0x08000000')
|
||||
sys.exit()
|
||||
if sys.platform == 'win32':
|
||||
# https://www.youtube.com/watch?v=AcrbUOhApd0
|
||||
os.chdir('C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin')
|
||||
#subprocess.Popen("STM32_Programmer_CLI.exe")
|
||||
subprocess.Popen("STM32_Programmer_CLI.exe")
|
||||
os.chdir(buildDirectory)
|
||||
sys.exit()
|
||||
|
||||
print('this platform is not supported by KED!')
|
Binary file not shown.
@ -0,0 +1,158 @@
|
||||
'''
|
||||
KED Main Script
|
||||
'''
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import flasher
|
||||
|
||||
####################################################################################################
|
||||
# FUTURE ACTIONS
|
||||
####################################################################################################
|
||||
# TODO: KeY 14_02_2023 -> Automatically generate project, if empty.
|
||||
# TODO: KeY 14_02_2023 -> Give the possibility to generate different example projects.
|
||||
####################################################################################################
|
||||
|
||||
####################################################################################################
|
||||
# MODIFICATIONS
|
||||
####################################################################################################
|
||||
# KeY 14_02_2023 : Some comments for code separation added :
|
||||
# FUTURE ACTIONS, MODIFICATIONS, FUNCTIONS and MAIN EXECUTION Delimiters
|
||||
#
|
||||
# KeY 14_02_2023 : Modified some Print's for user guidance and apearance changes
|
||||
# KeY 14_02_2023 : Gave a response to CSL_TO_USE question from Edwin
|
||||
####################################################################################################
|
||||
|
||||
####################################################################################################
|
||||
# FUNCTIONS
|
||||
####################################################################################################
|
||||
class bcolors:
|
||||
HEADER = '\033[95m'
|
||||
OKBLUE = '\033[94m'
|
||||
OKCYAN = '\033[96m'
|
||||
OKGREEN = '\033[92m'
|
||||
WARNING = '\033[93m'
|
||||
FAIL = '\033[91m'
|
||||
ENDC = '\033[0m'
|
||||
BOLD = '\033[1m'
|
||||
UNDERLINE = '\033[4m'
|
||||
|
||||
def getTargetDeviceList():
|
||||
os.chdir(os.path.join(os.getcwd(), 'csl'))
|
||||
# get top level folder names in csl which represent all available target devices
|
||||
return next(os.walk('.'))[1]
|
||||
|
||||
def build(TARGET_DEVICE):
|
||||
# TODO: ask Kerem what he wanted to to with "CSL_TO_USE"
|
||||
# KeY 14_02_2023 RESPONSE:
|
||||
# CSL_TO_USE is the "folder name" given to CMAKE
|
||||
# so that CMAKE gets the correct "file path" under the csl directory.
|
||||
# Like so: csl/<CSL_TO_USE> | Real example: csl/stm32f042
|
||||
|
||||
print('building project with cmake...')
|
||||
print(bcolors.OKGREEN)
|
||||
os.system('cmake -S . -B '+ buildDirectory + ' -DCSL_USED=' + TARGET_DEVICE)
|
||||
print(bcolors.ENDC)
|
||||
print('...done!')
|
||||
|
||||
print('Compiling Project with Make...')
|
||||
os.chdir(buildDirectory)
|
||||
print(bcolors.OKGREEN)
|
||||
os.system('make -j4')
|
||||
print(bcolors.ENDC)
|
||||
print('...done!')
|
||||
|
||||
'''
|
||||
def flash(TARGET_DEVICE):
|
||||
# find out what platform the build is done (e.g. linux, win32, etc.)
|
||||
|
||||
if sys.platform == 'linux':
|
||||
os.system('st-flash write' + TARGET_DEVICE + '.bin 0x08000000')
|
||||
if sys.platform == 'win32':
|
||||
# https://www.youtube.com/watch?v=AcrbUOhApd0
|
||||
os.chdir('C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin')
|
||||
subprocess.Popen("STM32_Programmer_CLI.exe")
|
||||
os.chdir(buildDirectory)
|
||||
|
||||
print('this platform is not supported by KED!')
|
||||
'''
|
||||
####################################################################################################
|
||||
|
||||
####################################################################################################
|
||||
# MAIN EXECUTION
|
||||
####################################################################################################
|
||||
scriptDirectory = os.getcwd()
|
||||
projectDirectory = os.path.join(scriptDirectory, '..')
|
||||
buildDirectory = os.path.join(projectDirectory, 'ked_build')
|
||||
#projectDirectory = scriptDirectory + '\\..'
|
||||
#buildDirectory = projectDirectory + '\\ked_build'
|
||||
|
||||
os.chdir(scriptDirectory)
|
||||
|
||||
# exit if no argument was passed
|
||||
argvLen = len(sys.argv)
|
||||
if argvLen < 2:
|
||||
print('Target Device missing as argument!')
|
||||
sys.exit()
|
||||
|
||||
# obtain list of all available targets in KED
|
||||
targetDevList = getTargetDeviceList()
|
||||
|
||||
# user requests help
|
||||
if sys.argv[1] in ('-h', '-help'):
|
||||
print('HELP -> TODO!')
|
||||
sys.exit()
|
||||
|
||||
# user request to remove build folder
|
||||
if sys.argv[1] in ('-rm', '-rmb'):
|
||||
if os.path.exists(buildDirectory):
|
||||
shutil.rmtree(buildDirectory)
|
||||
sys.exit()
|
||||
|
||||
# user requests listing of all available target devices
|
||||
# KeY 14_02_2023 : Could not help my self wiht some pimping
|
||||
if sys.argv[1] in ('-ls', '-lt', '-lst', '-lsd'):
|
||||
print('----------------------------')
|
||||
print('| Available Traget Devices |')
|
||||
print('----------------------------')
|
||||
|
||||
for targetDev in targetDevList:
|
||||
print(" - " + targetDev)
|
||||
sys.exit()
|
||||
|
||||
# user requests to clean project by erasing build
|
||||
if sys.argv[1] in ('-clean', '-c', '-db'):
|
||||
if os.path.exists(buildDirectory):
|
||||
shutil.rmtree(buildDirectory)
|
||||
os.mkdir(buildDirectory)
|
||||
print('build cleaned!')
|
||||
sys.exit()
|
||||
|
||||
if sys.argv[1] in ('-dox', '-doxygen', '-gd'):
|
||||
print('TODO: Implement doxygen generation')
|
||||
sys.exit()
|
||||
|
||||
if sys.argv[1] in ('-opendox', '-od'):
|
||||
print('TODO: Implement open doxygen in browser')
|
||||
sys.exit()
|
||||
|
||||
# check if requested target device is supported by KED
|
||||
# KeY : 14_02_2023 : Jsut changed the text a little bit and gave some guidance to the user.
|
||||
if sys.argv[1] not in targetDevList:
|
||||
print('debug: Invalid Target Device')
|
||||
print(' |-> To list the availabe target devices pass -ls as argument')
|
||||
print(' |-> python ked.py -ls')
|
||||
sys.exit()
|
||||
|
||||
print('building for target device ['+ bcolors.OKGREEN + sys.argv[1] + bcolors.ENDC + ']...')
|
||||
|
||||
#create build directory if missing
|
||||
if not os.path.exists(buildDirectory):
|
||||
os.mkdir(buildDirectory)
|
||||
|
||||
CSL_TO_USE = sys.argv[1]
|
||||
|
||||
build(CSL_TO_USE)
|
||||
#flasher.flash(CSL_TO_USE,buildDirectory)
|
||||
|
@ -0,0 +1,95 @@
|
||||
{
|
||||
"organization": "freeCodeCamp",
|
||||
"website": "https://www.freecodecamp.org/",
|
||||
"formed": 2014,
|
||||
"founder": "Quincy Larson",
|
||||
"certifications": [
|
||||
|
||||
{
|
||||
"name": "Responsive Web Design",
|
||||
"courses": [
|
||||
"HTML",
|
||||
"CSS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "JavaScript Algorithms and Data Structures",
|
||||
"courses": [
|
||||
"JavaScript"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Front End Development Libraries",
|
||||
"courses": [
|
||||
"Bootstrap",
|
||||
"jQuery",
|
||||
"Sass",
|
||||
"React",
|
||||
"Redux"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Data Visualization",
|
||||
"courses": [
|
||||
"D3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Relational Database Course",
|
||||
"courses": [
|
||||
"Linux",
|
||||
"SQL",
|
||||
"PostgreSQL",
|
||||
"Bash Scripting",
|
||||
"Git and GitHub",
|
||||
"Nano"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Back End Development and APIs",
|
||||
"courses": [
|
||||
"MongoDB",
|
||||
"Express",
|
||||
"Node",
|
||||
"NPM"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Quality Assurance",
|
||||
"courses": [
|
||||
"Testing with Chai",
|
||||
"Express",
|
||||
"Node"
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Scientific Computing with Python",
|
||||
"courses": [
|
||||
"Python"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Data Analysis with Python",
|
||||
"courses": [
|
||||
"Numpy",
|
||||
"Pandas",
|
||||
"Matplotlib",
|
||||
"Seaborn"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Information Security",
|
||||
"courses": [
|
||||
"HelmetJS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Machine Learning with Python",
|
||||
"courses": [
|
||||
"Machine Learning",
|
||||
"TensorFlow"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
import json
|
||||
|
||||
|
||||
with open('config.json', 'r') as config_file:
|
||||
config_data = json.load(config_file)
|
||||
# print(config_data)
|
||||
# print(json.dumps(config_data, indent=4))
|
||||
print(json.dumps(config_data, indent=4, sort_keys=True))
|
||||
|
@ -1,26 +0,0 @@
|
||||
#include "bsl_nucleo_f042k6.hpp"
|
||||
|
||||
|
||||
Nucleo_f042k6::Nucleo_f042k6(){}
|
||||
Nucleo_f042k6::~Nucleo_f042k6(){}
|
||||
|
||||
void Nucleo_f042k6::init()
|
||||
{
|
||||
ledPin.init();
|
||||
ledPin.setMode(Pin::mode::output);
|
||||
ledPin.setSpeed(Pin::speed::fast);
|
||||
|
||||
pin_a0.init();
|
||||
pin_a0.setMode(Pin::mode::input);
|
||||
pin_a0.setSpeed(Pin::speed::slow);
|
||||
pin_a0.setPullUpDonw(Pin::pullUpDown::pullDown);
|
||||
}
|
||||
|
||||
void Nucleo_f042k6::running()
|
||||
{
|
||||
ledPin.write(true);
|
||||
delay.ms(200);
|
||||
ledPin.write(false);
|
||||
delay.ms(200);
|
||||
}
|
||||
|
@ -1,111 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include(config_files/cmakeProjectConfig.cmake)
|
||||
|
||||
set(CSL_DIR ${CMAKE_SOURCE_DIR}/csl/${CSL_USED})
|
||||
|
||||
if(EXISTS ${CSL_DIR}) # Cheking if the directory exists
|
||||
message("${BoldGreen}Compiling for ${CSL_USED} ${ColourReset}")
|
||||
set(COMPILER_DEFS ${CSL_DIR}/compiler.cmake)
|
||||
set(PROJECT_DEFS ${CSL_DIR}/config.cmake)
|
||||
else()
|
||||
message( FATAL_ERROR "${BoldRed}Please Select a valid CSL, CMake will exit.${ColourReset}" )
|
||||
endif()
|
||||
|
||||
include(${COMPILER_DEFS})
|
||||
|
||||
project(${CSL_USED} ASM C CXX) #do this intead sf declaring languages in the beginning it will prevent loop errors.
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE off) #Shoul make print everythign ??
|
||||
set(EXECUTABLE ${PROJECT_NAME}) #Create the executable
|
||||
|
||||
####################################################################################################
|
||||
#CONFIG FILE
|
||||
####################################################################################################
|
||||
set(INTERFACES_DIR ${CMAKE_SOURCE_DIR}/csl/interfaces)
|
||||
set(UTILS_DIR ${CMAKE_SOURCE_DIR}/utils/assert)
|
||||
set(DRIVERS_DIR ${CMAKE_DRIVERS_DIR}/drivers)
|
||||
|
||||
####################################################################################################
|
||||
#SUBDIRECTORIES Will add the given folders to the porject an check for CmakeLists.txt
|
||||
####################################################################################################
|
||||
include(${PROJECT_DEFS})
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(csl)
|
||||
add_subdirectory(drivers)
|
||||
|
||||
message("${BoldBlue}Project Info ${ColourReset}")
|
||||
message("${Blue} |--> Exec Name \t: ${EXECUTABLE} ${ColourReset}")
|
||||
message("${Blue} |--> Compiler Def\t: ${COMPILER_DEFS} ${ColourReset}")
|
||||
message("${Blue} |--> Project Def\t: ${PROJECT_DEFS} ${ColourReset}")
|
||||
message("${Blue} |--> Interfaces Dir\t: ${INTERFACES_DIR} ${ColourReset}")
|
||||
message("${Blue} |--> Libs used\t\t: ${EXTRA_LIBS} ${ColourReset}")
|
||||
|
||||
####################################################################################################
|
||||
#EXECUTABLE
|
||||
####################################################################################################
|
||||
add_executable(${EXECUTABLE} ../main.c)
|
||||
target_compile_options(${EXECUTABLE} PRIVATE ${MAIN_FLAGS})
|
||||
target_compile_definitions(${EXECUTABLE} PRIVATE ${MAIN_DEFS})
|
||||
target_include_directories(${EXECUTABLE} PUBLIC ${MAIN_INCLUDES})
|
||||
|
||||
####################################################################################################
|
||||
#LINKING EXECUTEABLE
|
||||
####################################################################################################
|
||||
if(IS_NO_SYS)
|
||||
message("${Cyan}Using specifier Linker script ${ColourReset}")
|
||||
message("${Cyan} |--> ${LINKER} ${ColourReset}")
|
||||
|
||||
target_link_libraries(${EXECUTABLE} ${EXTRA_LIBS})
|
||||
target_link_options(${EXECUTABLE} PRIVATE ${LINKER_FLAGS})
|
||||
else ()
|
||||
message("${Cyan}Using systems linker ${ColourReset}")
|
||||
target_link_libraries(${EXECUTABLE} ${EXTRA_LIBS})
|
||||
endif()
|
||||
|
||||
####################################################################################################
|
||||
#CUSTOM COMMANDS
|
||||
####################################################################################################
|
||||
|
||||
if(NEED_OBJCOPY)
|
||||
add_custom_command(TARGET ${EXECUTABLE}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE} ${PROJECT_NAME}.hex
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE} ${PROJECT_NAME}.bin)
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET ${EXECUTABLE}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_SIZE} ${EXECUTABLE})
|
||||
|
||||
####################################################################################################
|
||||
#DOXYGEN
|
||||
####################################################################################################
|
||||
find_package(Doxygen)
|
||||
if (DOXYGEN_FOUND)
|
||||
# set input and output files
|
||||
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/config_files/doxyfile.in)
|
||||
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/doxyfile)
|
||||
|
||||
# request to configure the file
|
||||
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
|
||||
message("Doxygen build started")
|
||||
|
||||
# note the option ALL which allows to build the docs together with the application
|
||||
add_custom_target( doc_doxygen ALL
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen"
|
||||
VERBATIM )
|
||||
else (DOXYGEN_FOUND)
|
||||
message("Doxygen need to be installed to generate the doxygen documentation")
|
||||
endif (DOXYGEN_FOUND)
|
||||
####################################################################################################
|
||||
#CUSTOM Comments from dev.
|
||||
####################################################################################################
|
||||
# Link For header dependency : https://stackoverflow.com/questions/11216408/cmake-dependencies-headers-between-apps-libraries-in-same-project
|
||||
# This is one possible trick to handle the assenbly compiling.
|
||||
# We can't use arm-non-eabi-as because it can onaly hande macros.
|
||||
# So this bizzare Variable makes shure that whne the asembly compiling is called the -x assembler-with-cpp flag is passed
|
||||
# target_compile_options(${EXECUTABLE} PRIVATE
|
||||
# $<$<COMPILE_LANGUAGE:ASM>:-x assembler-with-cpp ${ASM_FLAGS}>)
|
@ -1 +0,0 @@
|
||||
add_subdirectory(${CSL_USED})
|
@ -1,90 +0,0 @@
|
||||
/**
|
||||
**************************************************************************************************
|
||||
* @file i2c.h
|
||||
* @author Kerem Yollu & Edwin Koch
|
||||
* @date 18.07.2022
|
||||
* @version 1.0
|
||||
**************************************************************************************************
|
||||
* @brief I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips :
|
||||
* following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA
|
||||
* This will also not have a I3C support for the forseable futrue.
|
||||
*
|
||||
* **Detailed Description :**
|
||||
*
|
||||
* I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips :
|
||||
* following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA
|
||||
* This will also not have a I3C support for the forseable futrue.
|
||||
*
|
||||
* @todo
|
||||
* - 18.07.2021 : Implement the i2c.c.
|
||||
**************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _I2C_H_
|
||||
#define _I2C_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define I2C_STATE_RESET 1 // Not Initialized
|
||||
#define I2C_STATE_READY 2 // Ready
|
||||
#define I2C_STATE_TX 4 // Transmitting
|
||||
#define I2C_STATE_RX 5 // Receiving
|
||||
#define I2C_STATE_LISTEN 6 // Listening
|
||||
#define I2C_STATE_ABORT 7 // Aborted by user
|
||||
#define I2C_STATE_TIMEOUT 8 // Timeout
|
||||
#define I2C_STATE_ERROR 9 // Error happened
|
||||
|
||||
#define I2C_SPEED_STANDART 1 // Sm 100 kbits/s This mode will be choosen for the constructor.
|
||||
#define I2C_SPEED_FAST 2 // Fm 400 kbits/s
|
||||
#define I2C_SPEED_FAST_PLUS 3 // Fm+ 1 Mbits/s
|
||||
#define I2C_SPEED_HIGH_SPEED 4 // Hs 3.4 Mbits/s
|
||||
#define I2C_SPEED_ULTRA_FAST 5 // UFm 5 Mbits/s
|
||||
|
||||
#define I2C_ADDRESS_7B 1 // 7 bits addressing mode
|
||||
#define I2C_ADDRESS_10B 2 // 10 bits addressing mode
|
||||
|
||||
#define I2C_MODE_MASTER 1 // Single Master Mode
|
||||
#define I2C_MODE_SLAVE 2 // Slave Mode
|
||||
#define I2C_MODE_MULTI_MASTER 3 // Multy Master Mode
|
||||
|
||||
/* Creator from the CPP Version PLease keep it to define the main init sequence.*/
|
||||
//ll_i2c(uint16_t address, uint8_t channel, uint8_t mode, uint8_t adressMode); // Creat i2c abject witha agiven channel address & mode speed is by default the slowest.
|
||||
|
||||
void i2cRead(uint8_t *reg, uint8_t *buffer, uint8_t ®Lenght, uint8_t &bufferLenght); // Defined by me : Read a given number of bytes
|
||||
void i2cWrite(uint8_t *reg, uint8_t *data, uint8_t ®Lenght, uint8_t &dataLenght); // Defined by me : Send a given number of bytes
|
||||
|
||||
uint8_t i2cTestDeviceSpeed(); // Defined by me : Cycle trough different modes until device cnat't answer fast enought
|
||||
uint8_t i2cDiscoverDevices(); // Defined by me : Scan the awailable address range on standart mode to find devices
|
||||
|
||||
void i2cInitChannelAsMaster(); // Hardware Specific : Initilise the hardware channel in master mode
|
||||
void i2cInitChannelAsSlave(); // Hardware Specific : Initilise the hardware channel in slavic mode (@life of boris)
|
||||
void i2cFreeChannel(); // Hardware Specific : Free the hardware channel for othe recousrces
|
||||
|
||||
void i2cClockSynchronise();// I2C Standart : Clock Syncronization
|
||||
void i2cReadDeviceInfo(); // I2c Standart : 3 Bytes (24 bits) | 12 Bits : Manufacturer info | 9 Bits: Part Identification | 3 Bits DIE Rev.
|
||||
void i2cAbortTransmit(); // I2c Standart : Stop Communication for multimaster mode
|
||||
void i2cClockStretch(); // I2C Standart : Optional For Pausing Communication because treatement takes longer than the communication
|
||||
void i2cArbitration(); // I2C Standart : Arbitration for multimaster mode to define the right master.
|
||||
void i2cSoftReset(); // I2C Standart : Software reset not supported by all hardware.
|
||||
void i2cBusClear(); // I2C Standart : in case if SCL is stuck
|
||||
|
||||
void i2cSetSpeed(uint8_t speed); // I2C Standart
|
||||
void i2cSetAddress(uint16_t &address); // I2C Standart
|
||||
void i2cSetAddressMode(); // I2C Standart
|
||||
|
||||
void i2cSetTimeout(uint8_t &timeout); // Hardware specific
|
||||
void i2cSetInterrupt(); // Hardware Specific
|
||||
void i2cSetDma(); // Hardware specific
|
||||
|
||||
void i2cThrowError(int16_t error); // Defined by me : Private error function for error handling
|
||||
void i2cPointReg(uint8_t *reg); // Defined by me : Points to the register to be red from
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _I2C_H_
|
@ -1,45 +0,0 @@
|
||||
/**
|
||||
**************************************************************************************************
|
||||
* @file spi.h
|
||||
* @author Kerem Yollu & Edwin Koch
|
||||
* @date 12.03.2022
|
||||
* @version 1.0
|
||||
**************************************************************************************************
|
||||
* @brief This is the genral interface for spi.
|
||||
*
|
||||
* **Detailed Description :**
|
||||
* This the spi interface and belongs to the interface layer.
|
||||
*
|
||||
**************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _SPI_H_
|
||||
#define _SPI_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hardwareDescription.h"
|
||||
|
||||
/** This is the spi hardware channel class*/
|
||||
|
||||
void spi_init(spiCH_t spi_hw_ch);
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Transmits and receives on byte of data
|
||||
* @param spi_hw_ch SPI hardware channel
|
||||
* @param tx_data 'tx_data' The byte to be transmitted"
|
||||
* @return The received data
|
||||
*/
|
||||
uint8_t spi_trx(spiCH_t spi_hw_ch, uint8_t tx_data);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _SPI_H_
|
||||
|
@ -1,25 +0,0 @@
|
||||
#ifndef _SPI_HPP_
|
||||
#define _SPI_HPP_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
template <typename Derived>
|
||||
struct SPI
|
||||
{
|
||||
uint8_t trx_u8(const uint8_t& data)
|
||||
{
|
||||
return static_cast<Derived*>(this)->trx_u8Impl(data);
|
||||
}
|
||||
|
||||
void tx(const uint8_t& data)
|
||||
{
|
||||
static_cast<Derived*>(this)->txImpl(data);
|
||||
}
|
||||
|
||||
uint8_t rx()
|
||||
{
|
||||
return static_cast<Derived*>(this)->rxImpl();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _SPI_HPP_
|
@ -1,82 +0,0 @@
|
||||
|
||||
|
||||
#ifndef _SPI_CH_H
|
||||
#define _SPI_CH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "pin.h"
|
||||
#include "spi.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// https://stackoverflow.com/questions/17052443/c-function-inside-struct
|
||||
typedef uint8_t (*readReg_t) (uint8_t);
|
||||
|
||||
|
||||
/*! \brief SPI cannel class
|
||||
* This class cpntains the pin and spi channel number
|
||||
* select.
|
||||
* */
|
||||
typedef struct{
|
||||
pinNo_t pin, /*!< pin number */
|
||||
spiCH_t spi /*!< spi hardware channel number */
|
||||
}spi_ch_t;
|
||||
|
||||
/**
|
||||
* \brief Read register
|
||||
* Read one byte from a one register with one byte address.
|
||||
* \param *spi_ch spi pointer to spi channel object
|
||||
* \param reg_address register address
|
||||
* \return register content
|
||||
*/
|
||||
uint8_t spiCH_readReg(spi_ch_t *spi_ch,
|
||||
uint8_t reg_address);
|
||||
|
||||
/**
|
||||
* \brief Read Block
|
||||
* Read a block of data starting at a given start address.
|
||||
* This function makes use of the auto register increment of the device to be read from.
|
||||
* The address will be sent once and then data is read.
|
||||
* \param *spi_ch pointer to spi cannel object
|
||||
* \param start_address start address to the first register
|
||||
* \param *buffer pointer to the buffer in which the read content is written into
|
||||
* \param buf_len length of buffer
|
||||
*/
|
||||
void spiCH_autoReadBlock(spi_ch_t *spi_ch,
|
||||
uint8_t start_address,
|
||||
uint8_t* buffer,
|
||||
uint8_t buf_len);
|
||||
|
||||
/**
|
||||
* \brief Write register
|
||||
* Write one byte to one register with one byte address.
|
||||
* \param *spi_ch pointer to spi channel object
|
||||
* \param reg_address register address
|
||||
* \param data data byte to be written into register
|
||||
*
|
||||
*/
|
||||
void spiCH_writeReg(spi_ch_t *spi_ch,
|
||||
uint8_t reg_address,
|
||||
uint8_t data);
|
||||
/**
|
||||
* \brief Write data block
|
||||
* Write a block of data starting at a given start address.
|
||||
* This function makes use of the auto register increment of the device to be written to. The
|
||||
* address will be sent once an then data is written.
|
||||
* \param *spi_ch pointer to spi channel object
|
||||
* \param start_address start address of the first reister
|
||||
* \param *data pointer to data to be written
|
||||
* \param data_len length of data to be written
|
||||
*/
|
||||
void spiCH_writeBlock(spi_ch_t *spi_ch,
|
||||
uint8_t start_address,
|
||||
const uint8_t *data,
|
||||
uint8_t data_len);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //_SPI_CH_H
|
||||
|
@ -1,75 +0,0 @@
|
||||
#ifndef _SPICH_HPP_
|
||||
#define _SPICH_HPP_
|
||||
|
||||
#include "pin.hpp"
|
||||
#include "spi.hpp"
|
||||
|
||||
// spi channel has a hardware spi object and a pin object for the chipselect.
|
||||
|
||||
template <typename DerivedPin,
|
||||
typename DerivedSPI>
|
||||
struct SPICH
|
||||
{
|
||||
SPICH(Pin<DerivedPin>& csPin,
|
||||
SPI<DerivedSPI>& spi) :
|
||||
chipSelect(csPin),
|
||||
spiHwCH(spi)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint8_t read_write_u8(const uint8_t& data)
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
// spiHwCH.takeMutex();
|
||||
chipSelect.write(false);
|
||||
|
||||
temp = spiHwCH.trx_u8(data);
|
||||
|
||||
chipSelect.write(true);
|
||||
// spiHwCH.releaseMutex();
|
||||
return temp;
|
||||
}
|
||||
|
||||
void readArray(const uint8_t& address,
|
||||
uint8_t* buffer,
|
||||
const uint8_t& len)
|
||||
{
|
||||
// spiHwCH.takeMutex();
|
||||
chipSelect.write(false);
|
||||
|
||||
spiHwCH.tx(address);
|
||||
|
||||
for(uint8_t i = 0; i < len;i++) {
|
||||
buffer[i] = spiHwCH.rx();
|
||||
};
|
||||
|
||||
chipSelect.write(true);
|
||||
// spiHwCH.releaseMutex();
|
||||
}
|
||||
|
||||
|
||||
void writeArray(const uint8_t& address,
|
||||
const uint8_t* buffer,
|
||||
const uint8_t& len)
|
||||
{
|
||||
chipSelect.write(false);
|
||||
|
||||
spiHwCH.tx(address);
|
||||
|
||||
for(uint8_t i = 0; i < len; i++) {
|
||||
spiHwCH.tx(buffer[i]);
|
||||
};
|
||||
|
||||
chipSelect.write(true);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// hardware resources
|
||||
Pin<DerivedPin>& chipSelect;
|
||||
SPI<DerivedSPI>& spiHwCH;
|
||||
};
|
||||
|
||||
#endif // _SPICH_HPP_
|
@ -1,5 +0,0 @@
|
||||
####################################################################################################
|
||||
#SUBDIRECTORIES
|
||||
####################################################################################################
|
||||
add_subdirectory(startup)
|
||||
add_subdirectory(Src)
|
@ -1,37 +0,0 @@
|
||||
|
||||
add_library(stmDelay delay.c)
|
||||
target_compile_options(stmDelay PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(stmDelay PRIVATE ${C_DEFS})
|
||||
target_include_directories(stmDelay PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::delay ALIAS stmDelay)
|
||||
|
||||
add_library(stmPin pin.c)
|
||||
target_compile_options(stmPin PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(stmPin PRIVATE ${C_DEFS})
|
||||
target_include_directories(stmPin PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::pin ALIAS stmPin)
|
||||
|
||||
add_library(stmUsart usart.c)
|
||||
target_compile_options(stmUsart PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(stmUsart PRIVATE ${C_DEFS})
|
||||
target_include_directories(stmUsart PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::usart ALIAS stmUsart)
|
||||
|
||||
add_library(stmInit deviceSetup.c)
|
||||
target_compile_options(stmInit PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(stmInit PRIVATE ${C_DEFS})
|
||||
target_include_directories(stmInit PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::init ALIAS stmInit)
|
||||
|
||||
add_library(stmTimer timer.c)
|
||||
target_compile_options(stmTimer PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(stmTimer PRIVATE ${C_DEFS})
|
||||
target_include_directories(stmTimer PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::timer ALIAS stmTimer)
|
||||
|
||||
add_library(stmSPI spi.c)
|
||||
target_compile_options(stmSPI PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(stmSPI PRIVATE ${C_DEFS})
|
||||
target_include_directories(stmSPI PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::spi ALIAS stmSPI)
|
||||
|
@ -1,56 +0,0 @@
|
||||
#include "spi.h"
|
||||
|
||||
#define SPI_BASE ((SPI_TypeDef *)spiBase_Addr_List[spi_hw_ch])
|
||||
|
||||
// https://controllerstech.com/spi-using-registers-in-stm32/
|
||||
|
||||
void spi_init(spiCH_t spi_hw_ch)
|
||||
{
|
||||
RCC->APB2ENR |= (1<<12); // Enable SPI1 CLock
|
||||
|
||||
SPI1->CR1 |= (1<<0)|(1<<1); // CPOL=1, CPHA=1
|
||||
|
||||
SPI1->CR1 |= (1<<2); // Master Mode
|
||||
|
||||
SPI1->CR1 |= (3<<3); // BR[2:0] = 011: fPCLK/16, PCLK2 = 80MHz, SPI clk = 5MHz
|
||||
|
||||
SPI1->CR1 &= ~(1<<7); // LSBFIRST = 0, MSB first
|
||||
|
||||
SPI1->CR1 |= (1<<8) | (1<<9); // SSM=1, SSi=1 -> Software Slave Management
|
||||
|
||||
SPI1->CR1 &= ~(1<<10); // RXONLY = 0, full-duplex
|
||||
|
||||
SPI1->CR1 &= ~(1<<11); // DFF=0, 8 bit data
|
||||
|
||||
SPI1->CR2 = 0;
|
||||
}
|
||||
|
||||
uint8_t spi_trx(spiCH_t spi_hw_ch, uint8_t tx_data)
|
||||
{
|
||||
uint8_t data;
|
||||
// example
|
||||
|
||||
|
||||
while (((SPI1->SR)&(1<<7))); // wait for BSY bit to Reset -> This will indicate that SPI is not busy in communication
|
||||
|
||||
SPI1->DR = tx_data; // send data
|
||||
|
||||
while (!((SPI1->SR) &(1<<0))); // Wait for RXNE to set -> This will indicate that the Rx buffer is not empty
|
||||
data = SPI1->DR;
|
||||
|
||||
return data;
|
||||
|
||||
// implementation 2. step
|
||||
#if 0
|
||||
// wait for SPY ready
|
||||
while((SPI_BASE->SR) & (1 << 7));
|
||||
|
||||
// load tx data
|
||||
SPI_BASE->DR = tx_data;
|
||||
|
||||
// Wait for RXNE flag to be set which indicates transmit complete
|
||||
while(!((SPI_BASE->SR) & (1<<0));
|
||||
|
||||
return SPI_BASE->DR;
|
||||
#endif
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue