Compare commits
102 Commits
interrupts
...
master
@ -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,138 @@
|
||||
/**
|
||||
**************************************************************************************************
|
||||
* @file hwd_pin.h
|
||||
* @author Kerem Yollu & Edwin Koch
|
||||
* @date 26.02.2023
|
||||
* @version 1.0
|
||||
**************************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* **Detailed Description :**
|
||||
*
|
||||
**************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _HWD_PIN_H_
|
||||
#define _HWD_PIN_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hardwareDescription.h"
|
||||
|
||||
#define MAX_N_PORTS_COUNT 3
|
||||
#define MAX_PORT_PINS_COUNT 16
|
||||
#define MAX_N_PIN_ALT_FUNC 8
|
||||
|
||||
#define MAX_PORT_A_PIN_NO 15
|
||||
#define MAX_PORT_B_PIN_NO 15
|
||||
#define MAX_PORT_F_PIN_NO 1
|
||||
|
||||
/*! Pin number typedef enum. It contains all the available pins */
|
||||
typedef enum
|
||||
{
|
||||
// NAME = BASE ADDR | PORT | PIN NO
|
||||
pinA0 = 0x00 | 0, /*!< Port: A Pin: 0 -> Port A Mask | Pin Mask */
|
||||
pinA1 = 0x00 | 1, /*!< Port: A Pin: 1 -> Port A Mask | Pin Mask */
|
||||
pinA2 = 0x00 | 2, /*!< Port: A Pin: 2 -> Port A Mask | Pin Mask */
|
||||
pinA3 = 0x00 | 3, /*!< Port: A Pin: 3 -> Port A Mask | Pin Mask */
|
||||
pinA4 = 0x00 | 4, /*!< Port: A Pin: 4 -> Port A Mask | Pin Mask */
|
||||
pinA5 = 0x00 | 5, /*!< Port: A Pin: 5 -> Port A Mask | Pin Mask */
|
||||
pinA6 = 0x00 | 6, /*!< Port: A Pin: 6 -> Port A Mask | Pin Mask */
|
||||
pinA7 = 0x00 | 7, /*!< Port: A Pin: 7 -> Port A Mask | Pin Mask */
|
||||
pinA8 = 0x00 | 8, /*!< Port: A Pin: 8 -> Port A Mask | Pin Mask */
|
||||
pinA9 = 0x00 | 9, /*!< Port: A Pin: 9 -> Port A Mask | Pin Mask */
|
||||
pinA10 = 0x00 | 10, /*!< Port: A Pin: 10 -> Port A Mask | Pin Mask */
|
||||
pinA11 = 0x00 | 11, /*!< Port: A Pin: 11 -> Port A Mask | Pin Mask */
|
||||
pinA12 = 0x00 | 12, /*!< Port: A Pin: 12 -> Port A Mask | Pin Mask */
|
||||
pinA13 = 0x00 | 13, /*!< Port: A Pin: 13 -> Port A Mask | Pin Mask */
|
||||
pinA14 = 0x00 | 14, /*!< Port: A Pin: 14 -> Port A Mask | Pin Mask */
|
||||
pinA15 = 0x00 | 15, /*!< Port: A Pin: 15 -> Port A Mask | Pin Mask */
|
||||
|
||||
pinB0 = 0x10 | 0, /*!< Port: B Pin: 0 -> Port B Mask | Pin Mask */
|
||||
pinB1 = 0x10 | 1, /*!< Port: B Pin: 1 -> Port B Mask | Pin Mask */
|
||||
pinB3 = 0x10 | 3, /*!< Port: B Pin: 3 -> Port B Mask | Pin Mask */
|
||||
pinB4 = 0x10 | 4, /*!< Port: B Pin: 4 -> Port B Mask | Pin Mask */
|
||||
pinB5 = 0x10 | 5, /*!< Port: B Pin: 5 -> Port B Mask | Pin Mask */
|
||||
pinB6 = 0x10 | 6, /*!< Port: B Pin: 6 -> Port B Mask | Pin Mask */
|
||||
pinB7 = 0x10 | 7, /*!< Port: B Pin: 7 -> Port B Mask | Pin Mask */
|
||||
pinB8 = 0x10 | 8, /*!< Port: B Pin: 8 -> Port B Mask | Pin Mask */
|
||||
|
||||
pinF0 = 0x20 | 0, /*!< Port: F Pin: 0 -> Port F Mask | Pin Mask */
|
||||
pinF1 = 0x20 | 1 /*!< Port: F Pin: 1 -> Port F Mask | Pin Mask */
|
||||
}pinNo_t;
|
||||
|
||||
/*!List of all possible port base addresses. This is used for the funcionality of of pin.h*/
|
||||
static const uint32_t portBase_Addr_List[MAX_N_PORTS_COUNT] = {
|
||||
GPIOA_BASE, //!< Base address Port A
|
||||
GPIOB_BASE, //!< Base address Port B
|
||||
GPIOF_BASE //!< Base address Port F
|
||||
};
|
||||
|
||||
/*! This is a bitmap list of all possible alternative functions for each pin.
|
||||
* 1means that there is an alternative function available and 0 for none. Tis is used
|
||||
* for the functionality in pin.h
|
||||
* */
|
||||
static const uint8_t altFunc_List[MAX_N_PORTS_COUNT][MAX_PORT_PINS_COUNT] = {
|
||||
{ // PORT A
|
||||
0b01110000, //PA0
|
||||
0b11110000, //PA1
|
||||
0b01110000, //PA2
|
||||
0b01110000, //PA3
|
||||
0b11111000, //PA4
|
||||
0b11110000, //PA5
|
||||
0b11110110, //PA6
|
||||
0b11111110, //PA7
|
||||
0b11111000, //PA8
|
||||
0b01111100, //PA9
|
||||
0b11111000, //PA10
|
||||
0b11111100, //PA11
|
||||
0b11111100, //PA12
|
||||
0b11100000, //PA13
|
||||
0b11000000, //PA14
|
||||
0b11110100 //PA15
|
||||
},
|
||||
{ // PORT B
|
||||
0b11110000, //PB0
|
||||
0b11110000, //PB1
|
||||
0b00010000, //PB2
|
||||
0b11110000, //PB3
|
||||
0b11110100, //PB4
|
||||
0b11110000, //PB5
|
||||
0b11110000, //PB6
|
||||
0b11110000, //PB7
|
||||
0b11111000, //PB8
|
||||
0b11111100, //PB9
|
||||
0b11110100, //PB10
|
||||
0b11100000, //PB11
|
||||
0b11100000, //PB12
|
||||
0b10100100, //PB13
|
||||
0b10100100, //PB14
|
||||
0b10100000 //PB15
|
||||
},
|
||||
{ // PORT F
|
||||
0b11000000, //PF0
|
||||
0b01000000, //PF1
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000 //N.A
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _HWD_PIN_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,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 @@
|
||||
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_ */
|
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_ */
|
@ -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,117 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include(config/cmakeProjectConfig.cmake)
|
||||
|
||||
set(CSL_DIR ${CMAKE_SOURCE_DIR}/csl/${CSL_USED})
|
||||
set(CSL_SOURCES ${CMAKE_SOURCE_DIR}/csl/${CSL_USED}/Src)
|
||||
|
||||
if(EXISTS ${CSL_DIR}) # Cheking if the directory exists
|
||||
message("${BoldGreen}Compiling for ${CSL_USED} ${ColourReset}")
|
||||
set(COMPILER_DEFS config/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(UTILS_DIR ${CMAKE_SOURCE_DIR}/utils/assert)
|
||||
set(DRIVERS_DIR ${CMAKE_SOURCE_DIR}/drivers)
|
||||
set(PERIFERALS_DIR ${CMAKE_SOURCE_DIR}/periferals)
|
||||
|
||||
set(OUTPUT_DOXYGEN TRUE)
|
||||
|
||||
####################################################################################################
|
||||
#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)
|
||||
add_subdirectory(periferals)
|
||||
|
||||
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
|
||||
####################################################################################################
|
||||
if(OUTPUT_DOXYGEN)
|
||||
find_package(Doxygen)
|
||||
if (DOXYGEN_FOUND)
|
||||
# set input and output files
|
||||
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/config/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)
|
||||
endif(OUTPUT_DOXYGEN)
|
||||
####################################################################################################
|
||||
#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}>)
|
@ -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()
|
@ -1 +0,0 @@
|
||||
add_subdirectory(${CSL_USED})
|
@ -1,4 +0,0 @@
|
||||
####################################################################################################
|
||||
#SUBDIRECTORIES
|
||||
####################################################################################################
|
||||
add_subdirectory(startup)
|
@ -1,304 +0,0 @@
|
||||
/**
|
||||
**************************************************************************************************
|
||||
* @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_USART_CHANNEL_COUNT 2
|
||||
#define MAX_I2C_CHANNEL_COUNT 1
|
||||
#define MAX_SPI_CHANNEL_COUNT 2
|
||||
#define MAX_I2S_CHANNEL_COUNT 2
|
||||
#define MAX_CAN_CHANNEL_COUNT 1
|
||||
#define MAX_TIMER_CHANNEL_COUNT 6
|
||||
|
||||
#define MAX_N_PORTS_COUNT 3
|
||||
#define MAX_PORT_PINS_COUNT 16
|
||||
#define MAX_N_PIN_ALT_FUNC 8
|
||||
|
||||
#define MAX_PORT_A_PIN_NO 15
|
||||
#define MAX_PORT_B_PIN_NO 15
|
||||
#define MAX_PORT_F_PIN_NO 1
|
||||
|
||||
/*! Pin number typedef enum. It contains all the available pins */
|
||||
typedef enum
|
||||
{
|
||||
// NAME = BASE ADDR | PORT | PIN NO
|
||||
pinA0 = 0x00 | 0, /*!< Port: A Pin: 0 -> Port A Mask | Pin Mask */
|
||||
pinA1 = 0x00 | 1, /*!< Port: A Pin: 1 -> Port A Mask | Pin Mask */
|
||||
pinA2 = 0x00 | 2, /*!< Port: A Pin: 2 -> Port A Mask | Pin Mask */
|
||||
pinA3 = 0x00 | 3, /*!< Port: A Pin: 3 -> Port A Mask | Pin Mask */
|
||||
pinA4 = 0x00 | 4, /*!< Port: A Pin: 4 -> Port A Mask | Pin Mask */
|
||||
pinA5 = 0x00 | 5, /*!< Port: A Pin: 5 -> Port A Mask | Pin Mask */
|
||||
pinA6 = 0x00 | 6, /*!< Port: A Pin: 6 -> Port A Mask | Pin Mask */
|
||||
pinA7 = 0x00 | 7, /*!< Port: A Pin: 7 -> Port A Mask | Pin Mask */
|
||||
pinA8 = 0x00 | 8, /*!< Port: A Pin: 8 -> Port A Mask | Pin Mask */
|
||||
pinA9 = 0x00 | 9, /*!< Port: A Pin: 9 -> Port A Mask | Pin Mask */
|
||||
pinA10 = 0x00 | 10, /*!< Port: A Pin: 10 -> Port A Mask | Pin Mask */
|
||||
pinA11 = 0x00 | 11, /*!< Port: A Pin: 11 -> Port A Mask | Pin Mask */
|
||||
pinA12 = 0x00 | 12, /*!< Port: A Pin: 12 -> Port A Mask | Pin Mask */
|
||||
pinA13 = 0x00 | 13, /*!< Port: A Pin: 13 -> Port A Mask | Pin Mask */
|
||||
pinA14 = 0x00 | 14, /*!< Port: A Pin: 14 -> Port A Mask | Pin Mask */
|
||||
pinA15 = 0x00 | 15, /*!< Port: A Pin: 15 -> Port A Mask | Pin Mask */
|
||||
|
||||
pinB0 = 0x10 | 0, /*!< Port: B Pin: 0 -> Port B Mask | Pin Mask */
|
||||
pinB1 = 0x10 | 1, /*!< Port: B Pin: 1 -> Port B Mask | Pin Mask */
|
||||
pinB3 = 0x10 | 3, /*!< Port: B Pin: 3 -> Port B Mask | Pin Mask */
|
||||
pinB4 = 0x10 | 4, /*!< Port: B Pin: 4 -> Port B Mask | Pin Mask */
|
||||
pinB5 = 0x10 | 5, /*!< Port: B Pin: 5 -> Port B Mask | Pin Mask */
|
||||
pinB6 = 0x10 | 6, /*!< Port: B Pin: 6 -> Port B Mask | Pin Mask */
|
||||
pinB7 = 0x10 | 7, /*!< Port: B Pin: 7 -> Port B Mask | Pin Mask */
|
||||
pinB8 = 0x10 | 8, /*!< Port: B Pin: 8 -> Port B Mask | Pin Mask */
|
||||
|
||||
pinF0 = 0x20 | 0, /*!< Port: F Pin: 0 -> Port F Mask | Pin Mask */
|
||||
pinF1 = 0x20 | 1 /*!< Port: F Pin: 1 -> Port F Mask | Pin Mask */
|
||||
}pinNo_t;
|
||||
|
||||
/*!List of all possible port base addresses. This is used for the funcionality of of pin.h*/
|
||||
static const uint32_t portBase_Addr_List[MAX_N_PORTS_COUNT] = {
|
||||
GPIOA_BASE, //!< Base address Port A
|
||||
GPIOB_BASE, //!< Base address Port B
|
||||
GPIOF_BASE //!< Base address Port F
|
||||
};
|
||||
|
||||
/*! This is a bitmap list of all possible alternative functions for each pin.
|
||||
* 1means that there is an alternative function available and 0 for none. Tis is used
|
||||
* for the functionality in pin.h
|
||||
* */
|
||||
static const uint8_t altFunc_List[MAX_N_PORTS_COUNT][MAX_PORT_PINS_COUNT] = {
|
||||
{ // PORT A
|
||||
0b01110000, //PA0
|
||||
0b11110000, //PA1
|
||||
0b01110000, //PA2
|
||||
0b01110000, //PA3
|
||||
0b11111000, //PA4
|
||||
0b11110000, //PA5
|
||||
0b11110110, //PA6
|
||||
0b11111110, //PA7
|
||||
0b11111000, //PA8
|
||||
0b01111100, //PA9
|
||||
0b11111000, //PA10
|
||||
0b11111100, //PA11
|
||||
0b11111100, //PA12
|
||||
0b11100000, //PA13
|
||||
0b11000000, //PA14
|
||||
0b11110100 //PA15
|
||||
},
|
||||
{ // PORT B
|
||||
0b11110000, //PB0
|
||||
0b11110000, //PB1
|
||||
0b00010000, //PB2
|
||||
0b11110000, //PB3
|
||||
0b11110100, //PB4
|
||||
0b11110000, //PB5
|
||||
0b11110000, //PB6
|
||||
0b11110000, //PB7
|
||||
0b11111000, //PB8
|
||||
0b11111100, //PB9
|
||||
0b11110100, //PB10
|
||||
0b11100000, //PB11
|
||||
0b11100000, //PB12
|
||||
0b10100100, //PB13
|
||||
0b10100100, //PB14
|
||||
0b10100000 //PB15
|
||||
},
|
||||
{ // PORT F
|
||||
0b11000000, //PF0
|
||||
0b01000000, //PF1
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000, //N.A
|
||||
0b00000000 //N.A
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* 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;
|
||||
|
||||
/*!
|
||||
* 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;
|
||||
|
||||
/*!
|
||||
* 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 enabcke 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 */
|
||||
};
|
||||
|
||||
/*!
|
||||
* 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
|
||||
};
|
||||
|
||||
/*! 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 // _hardwareDescription_H_
|
@ -1,280 +0,0 @@
|
||||
|
||||
#include "i2c.h"
|
||||
|
||||
#define I2C_BASE ((I2C_TypeDef*)i2cBase_Addr_List[i2cHardware->channelNo])
|
||||
|
||||
uint8_t temp8 = 0;
|
||||
uint16_t temp16 = 0;
|
||||
|
||||
void i2cEnableHardware(i2c_t *i2cHardware)
|
||||
{
|
||||
i2cHardwareReset(i2cHardware);
|
||||
|
||||
// Enables the i2c bus
|
||||
RCC->APB1ENR |= (1 << i2cBus_En_bitPos[i2cHardware->channelNo]);
|
||||
|
||||
pinInit(pinA9);
|
||||
pinInit(pinA10);
|
||||
pinConfig(pinA9, alternate, openDrain, pullUp, fast);// I2C SCL
|
||||
pinConfig(pinA10, alternate, openDrain, pullUp, fast);// I2C CSA
|
||||
pinSetAlternate(pinA9, 4);
|
||||
pinSetAlternate(pinA10, 4);
|
||||
}
|
||||
|
||||
void i2cHardwareReset(i2c_t *i2cHardware)
|
||||
{
|
||||
// Resete the I2C hardware using the reset registers,
|
||||
RCC->APB1RSTR |= (1 << i2cBus_Rst_bitPos[i2cHardware->channelNo]);
|
||||
RCC->APB1RSTR &= ~(1 << i2cBus_Rst_bitPos[i2cHardware->channelNo]);
|
||||
}
|
||||
|
||||
|
||||
void i2cEnablePeriferal(i2c_t *i2cHardware)
|
||||
{
|
||||
I2C_BASE->CR1 |= I2C_CR1_PE;
|
||||
}
|
||||
|
||||
void i2cDisablePeriferal(i2c_t *i2cHardware)
|
||||
{
|
||||
I2C_BASE->CR1 &= ~I2C_CR1_PE;
|
||||
}
|
||||
|
||||
|
||||
void i2cSetMode(i2c_t *i2cHardware, i2cMode_t mode)
|
||||
{
|
||||
//This device will set himself automatically to master mode
|
||||
if(i2cHardware->mode == i2cModeMaster)
|
||||
{
|
||||
//Automatic end mode (master mode) disabled Enablede as default
|
||||
I2C_BASE->CR2 &= ~I2C_CR2_AUTOEND;
|
||||
//I2C_BASE->CR2 |= I2C_CR2_AUTOEND;
|
||||
}
|
||||
else if(i2cHardware->mode == i2cModeSlave)
|
||||
{
|
||||
// to be written.
|
||||
}
|
||||
}
|
||||
|
||||
void i2cSetAddress(i2c_t *i2cHardware, uint16_t mainAddress, uint16_t secondAddress)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void i2cSetAddressLenght(i2c_t *i2cHardware, i2cAddressSize_t size)
|
||||
{
|
||||
if(i2cHardware->mode == i2cModeMaster)
|
||||
{
|
||||
if(i2cHardware->addressSize == i2cAddressSizeTenBits)
|
||||
{
|
||||
I2C_BASE->CR2 |= I2C_CR2_ADD10; // 10 Bit addressing
|
||||
I2C_BASE->CR2 &= ~I2C_CR2_HEAD10R; // 7 Bit header read turned on DEFAULT
|
||||
}
|
||||
else
|
||||
{
|
||||
I2C_BASE->CR2 &= ~I2C_CR2_ADD10; // 7 Bit addressing DEFAULT
|
||||
I2C_BASE->CR2 |= I2C_CR2_HEAD10R; // 7 Bit header read turned off DEFAULT
|
||||
}
|
||||
}
|
||||
else if(i2cHardware->mode == i2cModeSlave)
|
||||
{
|
||||
// to be written.
|
||||
}
|
||||
}
|
||||
|
||||
void i2cSetClockStretch(i2c_t *i2cHardware, i2cClockStretching_t stretching)
|
||||
{
|
||||
if(i2cHardware->stretching == i2cClockStretchingEnable)
|
||||
{
|
||||
I2C_BASE->CR1 &=~ I2C_CR1_NOSTRETCH;
|
||||
}
|
||||
else if(i2cHardware->stretching == i2cClockStretchingDisable)
|
||||
{
|
||||
I2C_BASE->CR1 |= I2C_CR1_NOSTRETCH;
|
||||
}
|
||||
}
|
||||
|
||||
void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed)
|
||||
{
|
||||
switch(speed)
|
||||
{
|
||||
case i2cSpeedStandart:
|
||||
I2C_BASE->TIMINGR = 0x2000090E;
|
||||
break;
|
||||
|
||||
case i2cSpeedFast:
|
||||
break;
|
||||
|
||||
case i2cSpeedFastPlus:
|
||||
break;
|
||||
|
||||
case i2cSpeedHightSpeed:
|
||||
break;
|
||||
|
||||
case i2cSpeedUltraFast:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void i2cConfigureFilters(i2c_t *i2cHardware)
|
||||
{
|
||||
//Anlalog filter is on
|
||||
I2C_BASE->CR1 &= ~I2C_CR1_ANFOFF;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
I2C Hardware functions
|
||||
***************************************************************************************************/
|
||||
|
||||
void i2cGenerateStart(i2c_t *i2cHardware)
|
||||
{
|
||||
I2C_BASE->CR2 &=~ I2C_CR2_STOP;
|
||||
I2C_BASE->CR2 |= I2C_CR2_START;
|
||||
//Wait until the start condition in generated.
|
||||
while(!(I2C_BASE->ISR & (I2C_ISR_BUSY)));
|
||||
i2cHardware->hardwareState = i2cHwStartGenerated;
|
||||
// This device places the salve address automaticalyy in the output buffer before sending the star condition
|
||||
i2cHardware->hardwareState = i2cHwOutputBufferFull;
|
||||
}
|
||||
|
||||
void i2cGenerateStop(i2c_t *i2cHardware)
|
||||
{
|
||||
// Send stop command
|
||||
I2C_BASE->CR2 |= I2C_CR2_STOP;
|
||||
I2C_BASE->CR2 &=~ I2C_CR2_START;
|
||||
i2cHardware->hardwareState = i2cHwStopGenerated;
|
||||
}
|
||||
|
||||
void i2cIsPeriferalReady(i2c_t *i2cHardware)
|
||||
{
|
||||
if((I2C_BASE->ISR & (I2C_ISR_BUSY))!=I2C_ISR_BUSY)
|
||||
{
|
||||
i2cHardware->periferalState = i2cPerifReady;
|
||||
}
|
||||
}
|
||||
|
||||
void i2cSetTransferCounter(i2c_t *i2cHardware, uint8_t count)
|
||||
{
|
||||
I2C_BASE->CR2 &= ~(0xFF << I2C_CR2_NBYTES_Pos);
|
||||
I2C_BASE->CR2 |= (count << I2C_CR2_NBYTES_Pos);
|
||||
}
|
||||
|
||||
void i2cSendSlaveAddress(i2c_t *i2cHardware, uint16_t *slaveAddress)
|
||||
{
|
||||
// The Slave addrress is automatically place on the output buffer (must be done before the start condition)
|
||||
I2C_BASE->CR2 |= (*slaveAddress & 0xff) << 1; // The bit no 0 is not taken in concideration in 7bit mode
|
||||
|
||||
i2cGenerateStart(i2cHardware);
|
||||
|
||||
// Wait until the data in the ouput buffer is put to the i2c BUS
|
||||
while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
|
||||
{
|
||||
i2cIsOutputBufferEmpty(i2cHardware);
|
||||
}
|
||||
}
|
||||
|
||||
void i2cSendRegisterAddress(i2c_t *i2cHardware, uint8_t *registerAddress)
|
||||
{
|
||||
i2cSendData(i2cHardware,registerAddress);
|
||||
}
|
||||
|
||||
void i2cInitiateWriteCommand(i2c_t *i2cHardware)
|
||||
{
|
||||
I2C_BASE->CR2 &= ~I2C_CR2_RD_WRN;
|
||||
}
|
||||
|
||||
void i2cInitiateReadCommand(i2c_t *i2cHardware)
|
||||
{
|
||||
I2C_BASE->CR2 |= I2C_CR2_RD_WRN;
|
||||
}
|
||||
|
||||
void i2cSendData(i2c_t *i2cHardware, uint8_t *registerAddress)
|
||||
{
|
||||
while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
|
||||
{
|
||||
i2cIsOutputBufferEmpty(i2cHardware);
|
||||
}
|
||||
i2cSetOutputRegister(i2cHardware,registerAddress);
|
||||
while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
|
||||
{
|
||||
i2cIsOutputBufferEmpty(i2cHardware);
|
||||
}
|
||||
}
|
||||
|
||||
void i2cIsOutputBufferEmpty(i2c_t *i2cHardware)
|
||||
{
|
||||
if((i2cHardware->periferalState) == i2cPerifTransmitting)
|
||||
{
|
||||
if((I2C_BASE->ISR & (I2C_ISR_TXIS)) == I2C_ISR_TXIS)
|
||||
{
|
||||
i2cHardware->hardwareState = i2cHwOutputBufferEmpty;
|
||||
}
|
||||
else
|
||||
{
|
||||
i2cHardware->hardwareState = i2cHwOutputBufferFull;
|
||||
}
|
||||
}
|
||||
else if((i2cHardware->periferalState) == i2cPerifRecieving)
|
||||
{
|
||||
if((I2C_BASE->ISR & (I2C_ISR_TXE)) == I2C_ISR_TXE)
|
||||
{
|
||||
i2cHardware->hardwareState = i2cHwOutputBufferEmpty;
|
||||
}
|
||||
else
|
||||
{
|
||||
i2cHardware->hardwareState = i2cHwOutputBufferFull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void i2cIsInputBufferEmpty(i2c_t *i2cHardware)
|
||||
{
|
||||
if((I2C_BASE->ISR & (I2C_ISR_RXNE)) == I2C_ISR_RXNE)
|
||||
{
|
||||
i2cHardware->hardwareState = i2cHwInputBufferFull;
|
||||
}
|
||||
else
|
||||
{
|
||||
i2cHardware->hardwareState = i2cHwInputBufferEmpty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void i2cReadInputRegister(i2c_t *i2cHardware, uint8_t *data)
|
||||
{
|
||||
*data = I2C_BASE->RXDR;
|
||||
}
|
||||
|
||||
void i2cSetOutputRegister(i2c_t *i2cHardware, uint8_t *data)
|
||||
{
|
||||
I2C_BASE->TXDR = *data;
|
||||
i2cHardware->hardwareState = i2cHwOutputBufferFull;
|
||||
}
|
||||
|
||||
void i2cIsTransferComplete(i2c_t *i2cHardware)
|
||||
{
|
||||
if((I2C_BASE->ISR & (I2C_ISR_TC)) == I2C_ISR_TC)
|
||||
{
|
||||
i2cHardware->periferalState = i2cPerifTransferComplete;
|
||||
}
|
||||
else
|
||||
{
|
||||
i2cHardware->periferalState = i2cPerifTransferOngoign;
|
||||
}
|
||||
}
|
||||
|
||||
void i2cGenerateNack(i2c_t *i2cHardware)
|
||||
{
|
||||
if(i2cHardware->mode == i2cModeMaster)
|
||||
{
|
||||
//IN master mode this ic geretes NACK's otomatically
|
||||
i2cHardware->hardwareState = i2cHwSentNack;
|
||||
}
|
||||
else if(i2cHardware->mode == i2cModeSlave)
|
||||
{
|
||||
// to be written.
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
project(Startup)
|
||||
|
||||
set (AS_SOURCES startup_stm32f042x6.s)
|
||||
set (AS_INCLUDES ${C_INCLUDES})
|
||||
set (AS_FLAGS -x assembler-with-cpp ${C_FLAGS})
|
||||
set (AS_DEFS ${C_DEFS})
|
||||
|
||||
add_library(${PROJECT_NAME} ${AS_SOURCES})
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE ${AS_FLAGS})
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE ${AS_DEFS})
|
||||
|
||||
#To create an alias to be used on the main CMAKE.
|
||||
add_library(sub::startup ALIAS ${PROJECT_NAME})
|
@ -1,2 +0,0 @@
|
||||
add_subdirectory(max7219)
|
||||
add_subdirectory(max31865)
|
@ -1,5 +0,0 @@
|
||||
add_library(MAX31865 max31865.c)
|
||||
target_compile_options(MAX31865 PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(MAX31865 PRIVATE ${C_DEFS})
|
||||
target_include_directories(MAX31865 PUBLIC . ${PERIFERALS_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::max31865 ALIAS MAX31865)
|
@ -1,5 +0,0 @@
|
||||
add_library(MAX7219 max7219.c)
|
||||
target_compile_options(MAX7219 PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(MAX7219 PRIVATE ${C_DEFS})
|
||||
target_include_directories(MAX7219 PUBLIC . ${PERIFERALS_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::max7219 ALIAS MAX7219)
|
@ -1,45 +0,0 @@
|
||||
add_library(SPI spi.c ${CSL_SOURCES}/imp_spi.c)
|
||||
target_compile_options(SPI PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(SPI PRIVATE ${C_DEFS})
|
||||
target_include_directories(SPI PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::spi ALIAS SPI)
|
||||
|
||||
add_library(DELAY ${CSL_SOURCES}/imp_delay.c)
|
||||
target_compile_options(DELAY PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(DELAY PRIVATE ${C_DEFS})
|
||||
target_include_directories(DELAY PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::delay ALIAS DELAY)
|
||||
|
||||
add_library(PIN ${CSL_SOURCES}/imp_pin.c)
|
||||
target_compile_options(PIN PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(PIN PRIVATE ${C_DEFS})
|
||||
target_include_directories(PIN PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::pin ALIAS PIN)
|
||||
|
||||
add_library(USART ${CSL_SOURCES}/imp_usart.c)
|
||||
target_compile_options(USART PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(USART PRIVATE ${C_DEFS})
|
||||
target_include_directories(USART PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::usart ALIAS USART)
|
||||
|
||||
# TODO: this point needs to be discussed. How should it work and what should it do?
|
||||
add_library(INIT ${CSL_SOURCES}/deviceSetup.c)
|
||||
target_compile_options(INIT PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(INIT PRIVATE ${C_DEFS})
|
||||
target_include_directories(INIT PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::init ALIAS INIT)
|
||||
|
||||
add_library(I2C i2c.c ${CSL_SOURCES}/imp_i2c.c)
|
||||
target_compile_options(I2C PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(I2C PRIVATE ${C_DEFS})
|
||||
target_include_directories(I2C PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::i2c ALIAS I2C)
|
||||
|
||||
add_library(TIMER ${CSL_SOURCES}/imp_timer.c)
|
||||
target_compile_options(TIMER PRIVATE ${C_FLAGS})
|
||||
target_compile_definitions(TIMER PRIVATE ${C_DEFS})
|
||||
target_include_directories(TIMER PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
|
||||
add_library(sub::timer ALIAS TIMER)
|
||||
|
||||
|
||||
|
@ -1,183 +0,0 @@
|
||||
#include "i2c.h"
|
||||
|
||||
//uint32_t i2cCR1;
|
||||
//uint32_t i2cCR2;
|
||||
//uint32_t i2cISR;
|
||||
|
||||
void i2cInit( i2c_t *i2cHardware,
|
||||
i2cCh_t channelNo,
|
||||
i2cMode_t mode,
|
||||
uint16_t mainAddress,
|
||||
uint16_t secondAddress,
|
||||
i2cAddressCount_t addressCount,
|
||||
i2cAddressSize_t addressSize,
|
||||
i2cSpeed_t speed,
|
||||
i2cOpperationMode_t opperationMode,
|
||||
i2cClockStretching_t stretching,
|
||||
i2cWakeUpTypes_t wakeOn)
|
||||
{
|
||||
i2cHardware->channelNo = channelNo;
|
||||
i2cHardware->mode = mode;
|
||||
i2cHardware->mainAddress = mainAddress;
|
||||
i2cHardware->secondAddress = secondAddress;
|
||||
i2cHardware->addressCount = addressCount;
|
||||
i2cHardware->addressSize = addressSize;
|
||||
i2cHardware->speed = speed;
|
||||
i2cHardware->opperationMode = opperationMode;
|
||||
i2cHardware->stretching = stretching;
|
||||
i2cHardware->wakeOn = wakeOn;
|
||||
i2cHardware->hardwareState = i2cHwIdle;
|
||||
i2cHardware->periferalState = i2cPerifNotInitialized;
|
||||
|
||||
i2cEnableHardware(i2cHardware);
|
||||
|
||||
i2cDisablePeriferal(i2cHardware);
|
||||
|
||||
i2cConfigureFilters(i2cHardware);
|
||||
|
||||
i2cSetClockStretch(i2cHardware, stretching);
|
||||
|
||||
i2cSetSpeed(i2cHardware, speed);
|
||||
|
||||
i2cSetMode(i2cHardware, opperationMode);
|
||||
|
||||
i2cSetAddressLenght(i2cHardware, addressSize);
|
||||
|
||||
i2cSetAddress(i2cHardware, mainAddress, secondAddress);
|
||||
|
||||
i2cEnablePeriferal(i2cHardware);
|
||||
|
||||
i2cHardware->periferalState = i2cPerifNotInitialized;
|
||||
}
|
||||
|
||||
|
||||
void i2cDeInit(i2c_t *i2cHardware)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void i2cRead(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
|
||||
{
|
||||
switch(i2cHardware->mode)
|
||||
{
|
||||
case i2cModeMaster:
|
||||
i2cMasterRecieve(i2cHardware, slaveAddress, registerAddress, data);
|
||||
break;
|
||||
case i2cModeSlave:
|
||||
break;
|
||||
case i2cModeMultyMaster:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// this function still doesn't implment 10 bit oopeartion
|
||||
void i2cMasterRecieve(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data)
|
||||
{
|
||||
switch(i2cHardware->opperationMode)
|
||||
{
|
||||
case i2cOpperationPolling :
|
||||
i2cMasterRecievePolling(i2cHardware, slaveAddress, registerAddress, data);
|
||||
break;
|
||||
case i2cOpperationInt:
|
||||
break;
|
||||
case i2cOpperationDma:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void i2cWrite(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
|
||||
{
|
||||
switch(i2cHardware->mode)
|
||||
{
|
||||
case i2cModeMaster:
|
||||
i2cMasterSend(i2cHardware, slaveAddress, registerAddress, data);
|
||||
break;
|
||||
case i2cModeSlave:
|
||||
break;
|
||||
case i2cModeMultyMaster:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void i2cMasterSend(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data)
|
||||
{
|
||||
switch(i2cHardware->opperationMode)
|
||||
{
|
||||
case i2cOpperationPolling :
|
||||
i2cMasterSendPolling(i2cHardware, slaveAddress, registerAddress, data);
|
||||
break;
|
||||
case i2cOpperationInt:
|
||||
break;
|
||||
case i2cOpperationDma:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void i2cMasterSendPolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data)
|
||||
{
|
||||
while(i2cHardware->periferalState != i2cPerifReady)
|
||||
{
|
||||
i2cIsPeriferalReady(i2cHardware);
|
||||
}
|
||||
|
||||
i2cHardware->periferalState = i2cPerifTransmitting;
|
||||
|
||||
i2cInitiateWriteCommand(i2cHardware);
|
||||
i2cSetTransferCounter(i2cHardware,2);
|
||||
i2cSendSlaveAddress(i2cHardware, slaveAddress);
|
||||
i2cSendRegisterAddress(i2cHardware,registerAddress);
|
||||
|
||||
i2cSendData(i2cHardware,data);
|
||||
|
||||
while(i2cHardware->periferalState != i2cPerifTransferComplete)
|
||||
{
|
||||
i2cIsTransferComplete(i2cHardware);
|
||||
}
|
||||
|
||||
i2cGenerateStop(i2cHardware);
|
||||
|
||||
i2cHardware->periferalState = i2cPerifReady;
|
||||
i2cHardware->hardwareState = i2cHwIdle;
|
||||
}
|
||||
|
||||
|
||||
void i2cMasterRecievePolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data)
|
||||
{
|
||||
while(i2cHardware->periferalState != i2cPerifReady)
|
||||
{
|
||||
i2cIsPeriferalReady(i2cHardware);
|
||||
}
|
||||
|
||||
i2cHardware->periferalState = i2cPerifTransmitting;
|
||||
|
||||
i2cSetTransferCounter(i2cHardware,1);
|
||||
i2cInitiateWriteCommand(i2cHardware);
|
||||
i2cSendSlaveAddress(i2cHardware, slaveAddress);
|
||||
i2cSendRegisterAddress(i2cHardware,registerAddress);
|
||||
|
||||
while(i2cHardware->periferalState != i2cPerifTransferComplete)
|
||||
{
|
||||
i2cIsTransferComplete(i2cHardware);
|
||||
}
|
||||
|
||||
i2cInitiateReadCommand(i2cHardware);
|
||||
i2cSendSlaveAddress(i2cHardware, slaveAddress);
|
||||
|
||||
i2cHardware->periferalState = i2cPerifRecieving;
|
||||
|
||||
while(i2cHardware->hardwareState != i2cHwInputBufferFull)
|
||||
{
|
||||
i2cIsInputBufferEmpty(i2cHardware);
|
||||
}
|
||||
|
||||
i2cGenerateNack(i2cHardware);
|
||||
i2cGenerateStop(i2cHardware);
|
||||
|
||||
i2cReadInputRegister(i2cHardware, data);
|
||||
|
||||
i2cHardware->periferalState = i2cPerifReady;
|
||||
i2cHardware->hardwareState = i2cHwIdle;
|
||||
}
|
||||
|
@ -1,552 +0,0 @@
|
||||
/**
|
||||
**************************************************************************************************
|
||||
* @file i2c.h
|
||||
* @author Kerem Yollu & Edwin Koch
|
||||
* @date 18.07.2022
|
||||
* @version 1.01
|
||||
**************************************************************************************************
|
||||
* @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
|
||||
* - 26.07.2021 : Implement the DMA
|
||||
* - 26.07.2021 : Implement the Interrupt
|
||||
* - 26.07.2021 : Implement the Sleep/WakeUp
|
||||
* - 26.07.2021 : Implement the Slave opperation
|
||||
**************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _I2C_H_
|
||||
#define _I2C_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hardwareDescription.h"
|
||||
#include "pin.h"
|
||||
|
||||
|
||||
|
||||
/*! Enum of possible I2C opperation modes */
|
||||
typedef enum{
|
||||
i2cModeMaster, /*!< Master mode : In Master mode, the I2C interface initiates
|
||||
a data transfer and generates the clock signal. **DEFAULT** */
|
||||
i2cModeMultyMaster, /*!< Multimaster Mode : In case if more than one master are present
|
||||
in one I2C bus. In such case each device needs to be able to
|
||||
cooperate knowing that another device could talking
|
||||
therefore the bus is busy (Arbirtation).
|
||||
For More information : https://www.i2c-bus.org/multimaster/ */
|
||||
i2cModeSlave /*!< Slave mode : A slave device has to always be ready to detect and
|
||||
process a start condition and to recognize its address */
|
||||
}i2cMode_t;
|
||||
|
||||
/*! Enum of possible I2C speeds */
|
||||
typedef enum{
|
||||
i2cSpeedStandart, /*!< SM 100 kbits/s Standart i2c Speed **DEFAULT** */
|
||||
i2cSpeedFast, /*!< FM 400 kbits/s */
|
||||
i2cSpeedFastPlus, /*!< FM+ 1 Mbits/s */
|
||||
i2cSpeedHightSpeed, /*!< HS 3.4 Mbits/s */
|
||||
i2cSpeedUltraFast /*!< UFM 5 Mbits/s */
|
||||
}i2cSpeed_t;
|
||||
|
||||
/*! Enum of possible I2C Adress sizes */
|
||||
typedef enum{
|
||||
i2cAddressSizeSevenBits, /*!< 7 Bits address size **DEFAULT** */
|
||||
i2cAddressSizeTenBits /*!< 10 Bits address size */
|
||||
}i2cAddressSize_t;
|
||||
|
||||
/*! Enum of possible I2C Address count */
|
||||
typedef enum{
|
||||
i2cAddressCountSingle, /*!< Only one address for communication **DEFAULT** */
|
||||
i2cAddressCountDual /*!< Dual addresses for one device respondng to two addresses */
|
||||
}i2cAddressCount_t;
|
||||
|
||||
/*! Enum for clock strechning activation. Can only be implmented as Slave
|
||||
* for more information : https://www.i2c-bus.org/clock-stretching/ */
|
||||
typedef enum{
|
||||
i2cClockStretchingDisable, /*!< We assume that the master and slave have compatible
|
||||
Clock frequencies **DEFAULT** */
|
||||
i2cClockStretchingEnable /*!< In situations where an I2C slave is not able to co-operate
|
||||
with the clock speed given by the master and needs to slow down.
|
||||
This is done by a mechanism referred to as clock stretching. */
|
||||
}i2cClockStretching_t;
|
||||
|
||||
/*! Enum for diffenrent wake up methodes wehnin sleep mode */
|
||||
typedef enum{
|
||||
i2cWakeUpDisabled, /*!< No wake up is possible this is the default mode also means that
|
||||
the sleep function is not implmentes **DEFAULT** */
|
||||
i2cWakeUpOnAddressMatch /*!< Wakes up on address match, this can be harware dependent */
|
||||
}i2cWakeUpTypes_t;
|
||||
|
||||
/*! Enum operation mode of the i2c channel */
|
||||
typedef enum{
|
||||
i2cOpperationPolling, /*!< Polling mode Blocking, i2c communication states are constantly
|
||||
checked on polling mode so it can be stoped
|
||||
when interrupts occures **DEFAULT** */
|
||||
i2cOpperationInt, /*!< Interrut Mode Non-blocking, i2c communications state changes
|
||||
generates an interrupt and can be handeled this way */
|
||||
i2cOpperationDma /*!< DMA Mode Non-blocking, I2C communication satets are managed
|
||||
via Inteerupts and with Direct Memory Access */
|
||||
}i2cOpperationMode_t;
|
||||
|
||||
/*! typedef for the i2c states*/
|
||||
typedef enum
|
||||
{
|
||||
i2cHwIdle, /*!< Hardware is in Idle Mode **DEFAULT** */
|
||||
i2cHwStartGenerated, /*!< Generated the star condition */
|
||||
i2cHwOutputBufferFull, /*!< The output buffer of the I2C Periferal is Full */
|
||||
i2cHwOutputBufferEmpty, /*!< The output buffer of the I2C Periferal is Empty */
|
||||
i2cHwInputBufferFull, /*!< The input buffer of the I2C Periferal Is Full */
|
||||
i2cHwInputBufferEmpty, /*!< The input buffer of the I2C Periferal Is Empty */
|
||||
i2cHwSentRead, /*!< Sent read request */
|
||||
i2cHwSentWrite, /*!< Sent write request */
|
||||
i2cHwGotAck, /*!< Recieved ACK */
|
||||
i2cHwGotNack, /*!< Recieved NACK */
|
||||
i2cHwSentAck, /*!< Sent ACK */
|
||||
i2cHwSentNack, /*!< Sent NACK */
|
||||
i2cHwStopGenerated, /*!< Generated the star condition */
|
||||
i2cHwError /*!< Error */
|
||||
} i2cHardwareState_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
i2cPerifNotInitialized, /*!< Default Peripheral is not yet Initialized **DEFAULT** */
|
||||
i2cPerifInitialized, /*!< I2C CHannle is initilized but not neceserly ready */
|
||||
i2cPerifSlaveAddressSent, /*!< The Salve Address Was Sent to the bus */
|
||||
i2cPerifTransferComplete, /*!< A full communication process is complete (wire or Read) */
|
||||
i2cPerifTransferOngoign, /*!< A full communication process is in progress (wire or Read) */
|
||||
i2cPerifReady, /*!< Peripheral Initialized and ready for use */
|
||||
i2cPerifSlaveNotFound, /*!< Desired Slave was not able to be found */
|
||||
i2cPerifTransmitting, /*!< Data Transmission process is ongoing */
|
||||
i2cPerifRecieving, /*!< Data Reception process is ongoing */
|
||||
i2cPerifListening, /*!< Address Listen Mode is ongoing */
|
||||
i2cPerifListeningAndTransmitting, /*!< Address Listen Mode and ongoing Data Transmission */
|
||||
i2cPerifListeningAndRecieveing, /*!< Address Listen Mode and ongoing Data Reception */
|
||||
i2cPerifAbort, /*!< Abort user request ongoing */
|
||||
i2cPerifTimeout, /*!< Timeout state */
|
||||
i2cPerifError /*!< Error */
|
||||
} i2cPeriferalState_t;
|
||||
|
||||
/*! Struture a an i2c channel with all the required propereties*/
|
||||
typedef struct i2c_t
|
||||
{
|
||||
i2cCh_t channelNo; /*!< The harware channel to be used */
|
||||
i2cMode_t mode; /*!< Master, Slave or Multymaster Modes */
|
||||
uint16_t mainAddress; /*!< First and Main address of the device */
|
||||
uint16_t secondAddress; /*!< Second address if dual addresse mode is configured */
|
||||
i2cAddressCount_t addressCount; /*!< Single or multiple */
|
||||
i2cAddressSize_t addressSize; /*!< 10 or 7 bit address size */
|
||||
i2cSpeed_t speed; /*!< Bus Speed */
|
||||
i2cOpperationMode_t opperationMode; /*!< Blocking or non blocking polling, Int or DMA */
|
||||
i2cClockStretching_t stretching; /*!< Clock Stretching enable onyl in slave mode */
|
||||
i2cWakeUpTypes_t wakeOn; /*!< Define on which type of action the i2c channel should
|
||||
wake up. Only if de prefiral goes to sleep */
|
||||
i2cHardwareState_t hardwareState; /*!< The current sitate of the I2C Bus */
|
||||
i2cPeriferalState_t periferalState; /*!< The current sitate of the I2C Bus */
|
||||
}i2c_t;
|
||||
|
||||
/***************************************************************************************************
|
||||
I2C Configuration functions
|
||||
***************************************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Initilize the I2C Hardware
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cInit( i2c_t *i2cHardware, /*!< Pointer to I2C hardware Object */
|
||||
i2cCh_t channelNo, /*!< The harware channel to be used */
|
||||
i2cMode_t mode, /*!< Master, Slave or Multymaster Modes */
|
||||
uint16_t mainAddress, /*!< First and Main address of the device */
|
||||
uint16_t secondAddress, /*!< Second address if dual addresse mode is configured */
|
||||
i2cAddressCount_t addressCount, /*!< Single or multiple */
|
||||
i2cAddressSize_t addressSize, /*!< 10 or 7 bit address size */
|
||||
i2cSpeed_t speed, /*!< Bus Speed */
|
||||
i2cOpperationMode_t opperationMode, /*!< Blocking or non blocking polling, Int or DMA */
|
||||
i2cClockStretching_t stretching, /*!< Clock Stretching enable onyl in slave mode */
|
||||
i2cWakeUpTypes_t wakeOn /*!< Wake up condition */
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief De-Initilize the I2C Hardware
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cDeInit(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Set the i2c channle to the gievn mode
|
||||
* @param Channel is the i2c hardware channel
|
||||
* @param mode The mode for i2c : Master Slave or Multymaster
|
||||
*/
|
||||
void i2cSetMode(i2c_t *i2cHardware, i2cMode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Set the i2c channles mode as Master Slave or Multymaster
|
||||
* @param i2cHardware is the i2c hardware channel
|
||||
* @param addressOne The forst address for the device
|
||||
* @param addressTwo The second address for the device only if dual address mode is not defined
|
||||
*/
|
||||
void i2cSetAddress(i2c_t *i2cHardware, uint16_t mainAddress, uint16_t secondAddress);
|
||||
|
||||
/**
|
||||
* @brief Set the i2c Address Lenght, 7 bit or 8 bit, Master or slave doesn't make any difference
|
||||
* @param i2cHardware is the i2c hardware channel
|
||||
* @param size Is the Adress isze to be used 7 Bit or 10 Bit
|
||||
*/
|
||||
void i2cSetAddressLenght(i2c_t *i2cHardware, i2cAddressSize_t size);
|
||||
|
||||
/**
|
||||
* @brief Stets the Communication speed
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param speed the different awailable speeds
|
||||
*/
|
||||
void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed);
|
||||
|
||||
/**
|
||||
* @brief Initiates the opperation mode for the selected i2c Channel
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param opperation define if the i2c channel will opperate on pollin, Interrupt, or DMA modes
|
||||
*/
|
||||
void i2cSetOpperation(i2c_t *i2cHardware, i2cOpperationMode_t opperation);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Ebales or disables clock stretching functionalities
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param The value to be written in the register. This will heavily depend on the hardware
|
||||
*/
|
||||
void i2cSetClockStretch(i2c_t *i2cHardware, i2cClockStretching_t stretching);
|
||||
|
||||
/**
|
||||
* @brief Set the wakeup mode
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param wake the desider wakeup mode for now i have found only one mode.
|
||||
*/
|
||||
void i2cSetWakeup(i2c_t *i2cHardware, i2cWakeUpTypes_t wake);
|
||||
|
||||
/**
|
||||
* @brief Configures Hardware implmente filters if there are any.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cConfigureFilters(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Set the timeout to close the i2c wait time if a communication fails.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param timeout the desider timeout duration in ticks.
|
||||
*/
|
||||
void i2cSetTimeout(i2c_t *i2cHardware, uint8_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Resets the i2c Periferal to it's inital state.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cPeriferalReset(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Resets the i2c Harware and register to it's factory deflauts.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cHardwareReset(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Enables I2C Hardware BUS & Clock & Pins
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cEnableHardware(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Enables I2C Periferal core.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cEnablePeriferal(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Disables I2C Periferal core.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cDisablePeriferal(i2c_t *i2cHardware);
|
||||
|
||||
/**************************************************************************************************
|
||||
I2C Communication functions independen of opperating mode
|
||||
***************************************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Writes the given amount of data to the selected device. This function will
|
||||
* automaticaly choose between i2cMasterSend(); or i2cSlaveSend();
|
||||
* Depending if the I2C channel was initiated as slave or master.
|
||||
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param slaveAddress is the address of the device to which the read command will be sent
|
||||
* @param registerAddress is the regiter to be red from the device
|
||||
* @param data is the data to be written
|
||||
* @param dataLenght is the total quantity of 8 bit data to be written.
|
||||
*/
|
||||
void i2cWrite(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
|
||||
|
||||
/**
|
||||
* @brief Reads the given amount of data to the selected device. This function will
|
||||
* automaticaly choose between i2cMasterRecieve(); or i2cSlaveRecieve();
|
||||
* Depending if the I2C channel was initiated as slave or master.
|
||||
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param slaveAddress is the address of the device to which the read command will be sent
|
||||
* @param registerAddress is the regiter to be red from the device
|
||||
* @param data is the data which has been red
|
||||
* @paran dataLenght is the total quantity of 8 bit data to be red
|
||||
*/
|
||||
void i2cRead(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
|
||||
|
||||
/**
|
||||
* @brief Recieve a Single Byte as master from from the given devices register.
|
||||
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param slaveAddress is the address of the device to which the read command will be sent
|
||||
* @param registerAddress is the regiter to be red from the device
|
||||
* @param data is the data whic has been red
|
||||
*/
|
||||
void i2cMasterRecieve(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
|
||||
/**
|
||||
* @brief Sends a Single Byte as master to the given devices register.
|
||||
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param slaveAddress is the address of the device to which the send command will be sent
|
||||
* @param registerAddress is the regiter to be written to the device
|
||||
* @param data is the data to be sent
|
||||
*/
|
||||
void i2cMasterSend(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
|
||||
|
||||
/**
|
||||
* @brief Recieve a Single Byte as slave from given devices register.
|
||||
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param slaveAddress is the address of the device to which the read command will be sent
|
||||
* @param registerAddress is the regiter to be red from the device
|
||||
* @param data is the data whic has been red
|
||||
*/
|
||||
void i2cSlaveRecieve(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
|
||||
|
||||
/**
|
||||
* @brief Recieve a Single Byte as slave from the given devices register.
|
||||
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param slaveAddress is the address of the device to which the read command will be sent
|
||||
* @param registerAddress is the regiter to be red from the device
|
||||
* @param data is the data whic has been red
|
||||
*/
|
||||
void i2cSlaveSend(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
|
||||
|
||||
/**************************************************************************************************
|
||||
I2C Hardware functions
|
||||
***************************************************************************************************/
|
||||
/**
|
||||
* @brief Checks if the device is ready for any type of communication
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cIsPeriferalReady(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Generates a Start condition.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cGenerateStart(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Generates a Start condition.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cGenerateStop(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Generates a NACK condition.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cGenerateNack(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Generates a ACK condition.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cGenerateAck(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Initiates the communication protocl by sending the slave address on the bus and waits
|
||||
* for an ACK (aknowledge)
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param slaveAddress The address of the slave to be communicated
|
||||
*/
|
||||
void i2cSendSlaveAddress(i2c_t *i2cHardware, uint16_t *slaveAddress);
|
||||
|
||||
/**
|
||||
* @brief Sende the register adrres with which we want to communicate.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param registerAddress The register address of the slave device that we are communication with
|
||||
*/
|
||||
void i2cSendRegisterAddress(i2c_t *i2cHardware, uint8_t *registerAddress);
|
||||
|
||||
/**
|
||||
* @brief Send the register that we want to read or write.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param registerAddress the register that need to be accessed
|
||||
*/
|
||||
void i2cSendData(i2c_t *i2cHardware, uint8_t *registerAddress);
|
||||
|
||||
/**
|
||||
* @brief Initiates a Write command with the previously set slave address.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cInitiateWriteCommand(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Initiates a read command with the previously set slave address.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cInitiateReadCommand(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Is the output buffer empty. This allso meas that the data that was in the ouput buffer
|
||||
* is sent to the i2c BUS.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cIsOutputBufferEmpty(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Is the output buffer empty. This allso meas that the data that was in the ouput buffer
|
||||
* is sent to the i2c BUS.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cIsInputBufferEmpty(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief reads the I2C input buffer
|
||||
* is sent to the i2c BUS.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param data pointer to the data that need to be read and returned
|
||||
*/
|
||||
void i2cReadInputRegister(i2c_t *i2cHardware, uint8_t *data);
|
||||
|
||||
/**
|
||||
* @brief writes to the I2C output buffer
|
||||
* is sent to the i2c BUS.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param data pointer to the data that need to be read and returned
|
||||
*/
|
||||
void i2cSetOutputRegister(i2c_t *i2cHardware, uint8_t *data);
|
||||
|
||||
/**
|
||||
* @brief Checks is transfer is complete
|
||||
* is sent to the i2c BUS.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param data pointer to the data that need to be read and returned
|
||||
*/
|
||||
void i2cIsTransferComplete(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Defines the amount of transfers to be made. Address exchange and start conditon does not count
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param count amount o data to be transfered.
|
||||
*/
|
||||
void i2cSetTransferCounter(i2c_t *i2cHardware, uint8_t count);
|
||||
/**************************************************************************************************
|
||||
I2C Communication functions Polling / Blocking Mode
|
||||
***************************************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Recieve a Single Byte in polling mode as master from from the given devices register.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param slaveAddress is the address of the device to which the read command will be sent
|
||||
* @param registerAddress is the regiter to be red from the device
|
||||
* @param data is the data whic has been red
|
||||
*/
|
||||
void i2cMasterRecievePolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
|
||||
/**
|
||||
* @brief Sends a Single Byte in polling mode as master to the given devices register.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param slaveAddress is the address of the device to which the send command will be sent
|
||||
* @param registerAddress is the regiter to be written to the device
|
||||
* @param data is the data to be sent
|
||||
*/
|
||||
void i2cMasterSendPolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
|
||||
|
||||
/**
|
||||
* @brief Recieve a Single Byte in polling mide as slave from the given devices register.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param slaveAddress is the address of the device to which the read command will be sent
|
||||
* @param registerAddress is the regiter to be red from the device
|
||||
* @param data is the data whic has been red
|
||||
*/
|
||||
void i2cSlaveRecievePolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
|
||||
|
||||
/**
|
||||
* @brief Recieve a Single Byte in polling mode as slave from the given devices register.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param slaveAddress is the address of the device to which the read command will be sent
|
||||
* @param registerAddress is the regiter to be red from the device
|
||||
* @param data is the data whic has been red
|
||||
*/
|
||||
void i2cSlaveSendPolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
|
||||
|
||||
/**************************************************************************************************
|
||||
I2C Arbitration Functions for Multymaster mode and slaves clock stretching
|
||||
***************************************************************************************************/
|
||||
void i2cClockSynchronise(); // I2C Standart : Clock Syncronization
|
||||
void i2cAbortTransmit(); // I2c Standart : Stop Communication for multimaster mode
|
||||
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
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
I2C Extra functions that are not esential for the main functionality
|
||||
***************************************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief This function will scan every for possible addresses to discover devices on the bus.
|
||||
* And write them to the Devices list given to him. This function will not discover more
|
||||
* devices than what he is told.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param devices list where the discevered devices will be written
|
||||
* @param deviceCount Max number of devices to be discovered.
|
||||
*/
|
||||
void i2cDiscoverDevices(i2c_t *i2cHardware, uint16_t *devices, uint8_t deviceCount);
|
||||
|
||||
/**
|
||||
* @brief This function will try to communicate with a device with every speed
|
||||
* allowed by his hardware to find out the maximum communication sppeed possible.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param slaveAddress is the address of the device to which the read command will be sent
|
||||
*/
|
||||
i2cSpeed_t i2cTestDeviceSpeed(i2c_t *i2cHardware, uint16_t *slaveAddress);
|
||||
|
||||
/**
|
||||
* @brief This function will read the device info register (if awailable) as follows :
|
||||
* I2c Standart : 3 Bytes (24 bits) | 12 Bits : Manufacturer info | 9 Bits: Part Identification | 3 Bits DIE Rev.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
* @param slaveAddress is the address of the device to be red
|
||||
*/
|
||||
uint32_t i2cReadDeviceInfo(i2c_t *i2cHardware, uint16_t *slaveAddress);
|
||||
|
||||
/**
|
||||
* @brief The selected i2c channel is put on sleep.
|
||||
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
|
||||
*/
|
||||
void i2cSleep(i2c_t *i2cHardware);
|
||||
|
||||
/**
|
||||
* @brief Error handling.
|
||||
* @param error The error no generated.
|
||||
*/
|
||||
void i2cThrowError(int16_t error); // Defined by me : Private error function for error handling
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _I2C_H_
|
@ -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)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue