Compare commits

..

9 Commits

7
.gitignore vendored

@ -96,10 +96,3 @@ build/
# vscode stuff
.vscode/
# python stuff
__pycache__/
# Doxygen
env/doc/html
env/doc/latex

@ -1,272 +0,0 @@
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}>)

@ -1,71 +1,19 @@
# KED: Wellcome to Kerem and Edwin's Develeppoment platform.
# KED
Kerems and Edwins Develeppoment platform.
# Workflow
##TODO: (In Chronological Form)
+ Implementing interrupt
+ Timer Together
+ GPIO Together/Alone
+ SPI Edwin
+ I2C Kerem
+ PWM Inlcuding Interrupts (Edwin &| Kerem)
+ Test KED with Reflow Oven
+ DMA
08.08.21 Kerem & Edwin
## Introduction:
### Why ?
This project is made to enable high portability between different Plaftorms an MCU's awailable on the market.
The main motivation was the chip allocation that started on 2018 and will most propably continue until 2024.
- Preparing the main implementation (dummy) of our structure which consists of :
- CSL : Chip Support Layer
- CSL for Raspberry
- CSL for STM Nucleo
- BSL : Board Support Layer
- BSL for Raspberry
- BSL for Oven Control
- Project Level
- Integrate BSL dummy fct. to our main.cpp
### But how come that we don't use the code renerators and IDEs proposed from the manufacturters ?
The answer is pretty simple :
+ We want this library to be portable between different manufacturers who uses arm cores.
+ To give us the ability to write and test our code on a raspberry and then simply implement the same code on your MCU.
+ To give us the opportunity the crate your own Board Support Layer based (BSL) on mutiple MCU if needed. Thus allowing us to adapt to a highly aggresive market.
+ An abstration layer that doesn't chnage between MCU's and BSL's with the miminun possible overhead as possible.
# How does it work ?
KED is intendet to be used as a git submodule. Allowing the mainternars of KED to do their things, while letting you to focus on your own project.
### Before you ask, Of Course, Yes, you would be one of our heroes if you decide to be a contributor !
# What is KED?
KED is a framework created by Kerem Yollu and Edwin Koch. KED stands for
"Kerem and Edwin Developement". The idea was initially started by the desire to create a hardware
abstraction layer (HAL) as the given ones are mostly bloated and not well structured.
# KED structure
This section will explain how KED is structured and how you can implement drivers, peripherals,
etc.
# Chip Support Layer (CSL)
The CSL folder holds all the target device specific resources and implementations. For example if
you want to use the NUCLEO 042k6 you have to choose the target device "stm32f042k6t6" as this is
the physical IC used by the NUCLEO board. This target device is represented inside CSL folder as a
folder named with the target device. This is crucial as there can be differeces between different
packages with the same IC core e.g "stm32f042k6t6" vs "stm32f042f6p6". Both of them are the "same"
but have different pin mappings and even differing peripheral structures.
## Hardware Description Layer
This is a subfolder inside each target device folder. It holds all the specific hardware
description headers e.g "hwd_pin.h". These HWD files describe e.g. how many pins there are, how
many timers there are, etc. If one target device does not have a specific peripheral e.g. CAN bus
then its HWD file is not put inside the folder.
## Implementing new target device
To implement a new target device to KED please follow the following steps in this section. Each
subsection will explaine how the structure is defined and what has to be implemented sothat at the
end there is a fully implemented
## Main structure of target device resources
Each target device has its own folder in which all the resorces and device specific implementations
are located. This folder is located to
in the csl folder of KED
## Implementing Peripherals
First create a folder with the spesific IC name. E.g. stm32f042k6t6 (used on the NUCLEO F042K6).
In this folder
TODO -> explain how to implement periperals and include
INTERFACES
@ -117,10 +65,3 @@ REFRESHERS
- tmux stuff
- change frame with `Ctrl+B W`. A widnow with a preview will open. Coose eather by moving
selection via cursor and the presseing `enter` or bynumber
RESTRUCTURATION 02_08_2023:
- Maybe : Separate the pripherals trio : Ex : i2c.h i2c.c imp_i2c.h as -> i2c.h i2c.c csl_i2c.h cls_i2c.c
- This mitigates confusion for end user and hides away complexity.

@ -1,51 +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_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_

@ -1,56 +0,0 @@
/**
**************************************************************************************************
* @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_

@ -1,144 +0,0 @@
/**
**************************************************************************************************
* @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_

@ -1,138 +0,0 @@
/**
**************************************************************************************************
* @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_

@ -1,70 +0,0 @@
/**
**************************************************************************************************
* @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_

@ -1,105 +0,0 @@
/**
**************************************************************************************************
* @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_

@ -1,30 +0,0 @@
/**
**************************************************************************************************
* @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_

@ -1,335 +0,0 @@
#include "i2c.h"
#include "usart.h"
#include "delay.h"
#define I2C_BASE ((I2C_TypeDef*)i2cBase_Addr_List[i2c_dev->channelNo])
void i2c_hardware_enable(i2c_t *i2c_dev)
{
i2c_hardware_reset(i2c_dev);
// Enables the i2c bus
RCC->APB1ENR |= (1 << i2cBus_En_bitPos[i2c_dev->channelNo]);
i2c_dev->hardwareState = i2c_hw_enabled;
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);
i2c_dev->hardwareState = i2c_hw_ready;
}
// Resets the I2C hardware using the reset registers,
// This will init the device to it's defualt configuration established by STM
void i2c_hardware_reset(i2c_t *i2c_dev)
{
RCC->APB1RSTR |= (1 << i2cBus_Rst_bitPos[i2c_dev->channelNo]);
RCC->APB1RSTR &= ~(1 << i2cBus_Rst_bitPos[i2c_dev->channelNo]);
i2c_dev->hardwareState = i2c_hw_reset;
}
//enables periferal
void i2c_periferal_enable(i2c_t *i2c_dev)
{
I2C_BASE->CR1 |= I2C_CR1_PE;
i2c_dev->periferalState = i2c_perif_enabled;
//Wait untill periferal is ready for communication
while(!i2c_is_perif_ready(i2c_dev));
i2c_dev->periferalState = i2c_perif_ready;
}
void i2c_periferal_disable(i2c_t *i2c_dev)
{
I2C_BASE->CR1 &= ~I2C_CR1_PE;
i2c_dev->periferalState = i2c_perif_disabled;
}
void i2c_set_mode(i2c_t *i2c_dev, i2c_mode_t mode)
{
//This device will set himself automatically to master mode
if(i2c_dev->mode == i2c_mode_master)
{
}
else if(i2c_dev->mode == i2c_mode_slave)
{
// to be written.
}
}
void i2c_set_address_lenght(i2c_t *i2c_dev, i2c_address_size_t size)
{
if(i2c_dev->mode == i2c_mode_master)
{
if(i2c_dev->addressSize == i2c_address_size_10b)
{
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(i2c_dev->mode == i2c_mode_slave)
{
// to be written.
}
}
void i2c_set_clk_stretch(i2c_t *i2c_dev, i2c_clk_stretching_t stretching)
{
if(i2c_dev->stretching == i2c_clk_stretching_enable)
{
I2C_BASE->CR1 &=~ I2C_CR1_NOSTRETCH;
}
else if(i2c_dev->stretching == i2c_clk_stretching_disable)
{
I2C_BASE->CR1 |= I2C_CR1_NOSTRETCH;
}
}
void i2c_set_clk_speed(i2c_t *i2c_dev, i2c_clk_speed_t speed)
{
switch(speed)
{
case i2c_clk_speed_standart:
I2C_BASE->TIMINGR = 0x2000090E;
break;
case i2c_clk_speed_fast:
break;
case i2c_clk_speed_fastPlus:
break;
case i2c_clk_speed_hightSpeed:
break;
case i2c_clk_speed_ultraFast:
break;
default:
break;
}
}
void i2c_set_filter(i2c_t *i2c_dev, uint8_t enable)
{
if(enable)
{
//Anlalog filter is on
I2C_BASE->CR1 &= ~I2C_CR1_ANFOFF;
}
else
{
//Anlalog filter is off
I2C_BASE->CR1 |= I2C_CR1_ANFOFF;
}
}
/**************************************************************************************************
I2C Hardware functions
***************************************************************************************************/
void i2c_send_start(i2c_t *i2c_dev)
{
I2C_BASE->CR2 &=~ I2C_CR2_STOP;
I2C_BASE->CR2 |= I2C_CR2_START;
//Wait until the start condition in generated.
//Bit 15BUSY: Bus busy
//This flag indicates that a communication is in progress on the bus. It is set by hardware when a
//START condition is detected. It is cleared by hardware when a Stop condition is detected, or
//when PE=0.
while(!(I2C_BASE->ISR & (I2C_ISR_BUSY)));
i2c_dev->hardwareState = i2c_hw_sent_start;
}
void i2c_send_stop(i2c_t *i2c_dev)
{
// Send stop command
I2C_BASE->CR2 |= I2C_CR2_STOP;
I2C_BASE->CR2 &=~ I2C_CR2_START;
i2c_dev->hardwareState = i2c_hw_sent_stop;
}
uint8_t i2c_is_perif_ready(i2c_t *i2c_dev)
{
if((I2C_BASE->ISR & (I2C_ISR_BUSY))!=I2C_ISR_BUSY)
{
i2c_dev->periferalState = i2c_perif_ready;
return 1;
}
return 0;
}
void i2c_set_transfer_counter(i2c_t *i2c_dev, uint8_t count)
{
I2C_BASE->CR2 &= ~(0xFF << I2C_CR2_NBYTES_Pos);
I2C_BASE->CR2 |= (count << I2C_CR2_NBYTES_Pos);
}
uint8_t i2c_get_transfer_counter(i2c_t *i2c_dev)
{
return (I2C_BASE->CR2 & I2C_CR2_NBYTES) >> I2C_CR2_NBYTES_Pos;
}
void i2c_init_write_command(i2c_t *i2c_dev)
{
I2C_BASE->CR2 &= ~I2C_CR2_RD_WRN;
i2c_dev->hardwareState = i2c_hw_send_write;
}
void i2c_init_read_command(i2c_t *i2c_dev)
{
I2C_BASE->CR2 |= I2C_CR2_RD_WRN;
i2c_dev->hardwareState =i2c_hw_send_read;
}
uint8_t i2c_send_address_for_write(i2c_t *i2c_dev, uint16_t *slaveAddress)
{
//Automatic end mode (master mode) disabled Enablede as default
I2C_BASE->CR2 &= ~I2C_CR2_AUTOEND;
// On This chip this shoudl be done before the start condition
i2c_init_write_command(i2c_dev);
// 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
// This device places the salve address automaticaly in the output buffer before sending the star condition
i2c_send_start(i2c_dev);
while(i2c_is_output_buffer_full(i2c_dev));
return 1;
}
uint8_t i2c_send_address_for_read(i2c_t *i2c_dev, uint16_t *slaveAddress)
{
// On This chip this shoudl be done before the start condition
i2c_init_read_command(i2c_dev);
// 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
// This device places the salve address automaticaly in the output buffer before sending the star condition
i2c_send_start(i2c_dev);
while(i2c_is_output_buffer_full(i2c_dev));
return 1;
}
uint8_t i2c_is_output_buffer_full(i2c_t *i2c_dev)
{
/*
Bit 0 TXE: Transmit data register empty (transmitters)
This bit is set by hardware when the I2C_TXDR register is empty. It is cleared when the next
data to be sent is written in the I2C_TXDR register.
This bit can be written to 1 by software in order to flush the transmit data register I2C_TXDR.
Note: This bit is set by hardware when PE=0.
*/
if(I2C_BASE->ISR & I2C_ISR_TXE)
{
i2c_dev->hardwareState = i2c_hw_out_buff_empty;
return 0;
}
else
{
i2c_dev->hardwareState = i2c_hw_out_buff_full;
return 1;
}
}
uint8_t i2c_is_txis(i2c_t *i2c_dev)
{
if(I2C_BASE->ISR & I2C_ISR_TXIS)
{
i2c_dev->hardwareState = i2c_hw_out_buff_empty;
return 0;
}
else
{
i2c_dev->hardwareState = i2c_hw_out_buff_full;
return 1;
}
}
void i2c_send_reg_address(i2c_t *i2c_dev, uint8_t *registerAddress)
{
I2C_BASE->TXDR = *registerAddress;
i2c_dev->hardwareState = i2c_hw_out_buff_full;
while(i2c_is_output_buffer_full(i2c_dev));
}
void i2c_send_data(i2c_t *i2c_dev, uint8_t *data)
{
I2C_BASE->TXDR = *data;
i2c_dev->hardwareState = i2c_hw_out_buff_full;
while(i2c_is_output_buffer_full(i2c_dev));
}
uint8_t i2c_is_transfer_complete(i2c_t *i2c_dev)
{
/*
TC: Transfer Complete (master mode)
This flag is set by hardware when RELOAD=0, AUTOEND=0 and NBYTES data have been
transferred. It is cleared by software when START bit or STOP bit is set.
Note: This bit is cleared by hardware when PE=0.
*/
if(I2C_BASE->ISR & I2C_ISR_TC)
{
return 1;
}
else
{
return 0;
}
}
uint8_t i2c_is_input_buffer_full(i2c_t *i2c_dev)
{
if(I2C_BASE->ISR & I2C_ISR_RXNE)
{
i2c_dev->hardwareState = i2c_hw_in_buff_full;
return 1;
}
else
{
i2c_dev->hardwareState = i2c_hw_in_buff_empty;
return 0;
}
}
void i2c_get_input_register(i2c_t *i2c_dev, uint8_t *data)
{
while(!i2c_is_input_buffer_full(i2c_dev));
*data = I2C_BASE->RXDR;
while(!i2c_is_transfer_complete(i2c_dev));
}
void i2c_send_nack(i2c_t *i2c_dev)
{
if(i2c_dev->mode == i2c_mode_master)
{
//IN master mode this ic geretes NACK's otomatically
i2c_dev->hardwareState = i2c_hw_sent_nack;
}
else if(i2c_dev->mode == i2c_mode_slave)
{
// to be written.
}
}
uint8_t i2c_check_nack(i2c_t *i2c_dev)
{
delayMs(2);
return(I2C_BASE->ISR & I2C_ISR_NACKF);
}
void i2c_set_address(i2c_t *i2c_dev, uint16_t address){}
void i2c_set_address_second(i2c_t *i2c_dev, uint16_t address){}

@ -1,153 +0,0 @@
#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]);
}

@ -1 +0,0 @@
set(DRIVERS_LIST lcd_oled max7219 max31865 ssd1306_i2c)

@ -1,96 +0,0 @@
# 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/).
---

@ -1,357 +0,0 @@
#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, &reg, &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, &reg, &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);
}
}
}

@ -1,78 +0,0 @@
#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.

@ -1,287 +0,0 @@
/*********************************************************************
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);
}

@ -1,173 +0,0 @@
/*********************************************************************
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_ */

26
env/$ vendored

@ -0,0 +1,26 @@
#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);
}

117
env/CMakeLists.txt vendored

@ -0,0 +1,117 @@
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}>)

@ -1,150 +0,0 @@
####################################################################################################
# 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()

@ -1,47 +0,0 @@
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,29 +0,0 @@
####################################################################################################
# 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()

@ -1,67 +0,0 @@
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,6 +1,4 @@
####################################################################################################
# CMAKE Colors
####################################################################################################
if(NOT WIN32)
string(ASCII 27 Esc)
set(ColourReset "${Esc}[m")

@ -0,0 +1 @@
add_subdirectory(${CSL_USED})

@ -0,0 +1,4 @@
####################################################################################################
#SUBDIRECTORIES
####################################################################################################
add_subdirectory(startup)

@ -0,0 +1,339 @@
/**
**************************************************************************************************
* @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
};
// Interrupts
/*! interrupt types. These act as indexes for the */
typedef enum {
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,
intTypeEND
}intrType_t;
uint32_t intHandlerList[intTypeEND]={
0,0,0,0,0,0,0,0,0,0};
static const uint8_t interruptTypeIndexList[intTypeEND] =
{
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn
};
#ifdef __cplusplus
}
#endif
#endif // _hardwareDescription_H_

@ -1,4 +1,4 @@
#include "deviceSetup.h"
#include"deviceSetup.h"
#include "stm32f042x6.h"
@ -8,7 +8,6 @@
#define CLEAR_REG(REG) ((REG) = (0x0))
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
#define READ_REG(REG) ((REG))
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
// FLASH->ACR = (((FLASH->ACR) & (~(FLASH_ACR_LATENCY))) | 0)
#define SYS_CLK 8000000
@ -19,7 +18,6 @@ void setupInit()
setupBus();
setupMemory();
setupClock();
__disable_irq();
setupPower();
delayInitMs(SYS_CLK, 1000);
}

@ -0,0 +1,280 @@
#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.
}
}

@ -0,0 +1,97 @@
#include "interrupt.h"
static void defaultHandler(){};
// pointers to dedicated interrupt handlers
void intInit(
intrType_t intType,
intHandler_t handler,
uint8_t priority)
{
NVIC_SetPriority(interruptTypeIndexList[intType], priority);
// TODO: add index ceck!
intHandlerList[intType] = (uint32_t)handler;
}
void intEnableAll()
{
__enable_irq();
}
void intDissableAll()
{
__disable_irq();
}
void intEnable(
intrType_t intType)
{
NVIC_EnableIRQ(interruptTypeIndexList[intType]);
}
void intDissable(
intrType_t intType)
{
NVIC_DisableIRQ(interruptTypeIndexList[intType]);
}
// Interrupt service routines
void TIM2_IRQHandler()
{
if(TIM2->SR & TIM_SR_UIF) {
// clear flag
TIM2-> SR &= ~TIM_SR_UIF;
//TODO: call handler here
((intHandler_t)(intHandlerList[TIM2_UPDATE]))();
}
if(TIM2->SR & TIM_SR_CC1IF) {
TIM2-> SR &= ~TIM_SR_CC1IF;
}
if(TIM2->SR & TIM_SR_CC2IF) {
TIM2-> SR &= ~TIM_SR_CC2IF;
}
if(TIM2->SR & TIM_SR_CC3IF) {
TIM2-> SR &= ~TIM_SR_CC3IF;
}
if(TIM2->SR & TIM_SR_CC4IF) {
TIM2-> SR &= ~TIM_SR_CC4IF;
}
if(TIM2->SR & TIM_SR_TIF) {
TIM2-> SR &= ~TIM_SR_TIF;
}
if(TIM2->SR & TIM_SR_CC1OF) {
TIM2-> SR &= ~TIM_SR_CC1OF;
}
if(TIM2->SR & TIM_SR_CC2OF) {
TIM2-> SR &= ~TIM_SR_CC2OF;
}
if(TIM2->SR & TIM_SR_CC3OF) {
TIM2-> SR &= ~TIM_SR_CC3OF;
}
if(TIM2->SR & TIM_SR_CC4OF) {
TIM2-> SR &= ~TIM_SR_CC4OF;
}
}

@ -205,3 +205,6 @@ void pinThrowError(pinErrors_t error)
{
while(1);
}

@ -1,7 +1,5 @@
#include "spi.h"
#include "hardwareDescription.h"
#include "hwd_spi.h"
#include "interrupt.h"
#define SPI_BASE ((SPI_TypeDef *)spiBase_Addr_List[spi_hw_ch])
@ -147,15 +145,3 @@ uint8_t spiTrx8BitPolling(spiCH_t spi_hw_ch, uint8_t tx_data)
return *(uint8_t*)&(SPI_BASE->DR);
}
// Interrupt Service Routines
void SPI1_IRQHandle()
{
//HANDLE_INT_FLAG(SPI1->SR, );
}
void SPI2_IRQHandle()
{
}

@ -1,54 +1,7 @@
#include "timer.h"
#include "interrupt.h"
#include "hwd_interrupt.h"
#include <stdlib.h>
#define BASE ((TIM_TypeDef *)timerBase_Addr_List[timer])
// debug notes: the makro works. what seems to not work is the indexing and calling the handler!
static const uint32_t DIER_list[41] = {
TIM_DIER_BIE,// timer 1
TIM_DIER_UIE,
TIM_DIER_TIE,
TIM_DIER_COMIE,
TIM_DIER_CC1IE,
TIM_DIER_CC2IE,
TIM_DIER_CC3IE,
TIM_DIER_CC4IE,
TIM_DIER_UIE,// timer 2
TIM_DIER_CC1IE,
TIM_DIER_CC2IE,
TIM_DIER_CC3IE,
TIM_DIER_CC4IE,
TIM_DIER_TIE,
TIM_DIER_CC1IE,
TIM_DIER_CC2IE,
TIM_DIER_CC3IE,
TIM_DIER_CC4IE,
TIM_DIER_UIE, // timer 3
TIM_DIER_CC1IE,
TIM_DIER_CC2IE,
TIM_DIER_CC3IE,
TIM_DIER_CC4IE,
TIM_DIER_TIE,
TIM_DIER_CC1IE,
TIM_DIER_CC2IE,
TIM_DIER_CC3IE,
TIM_DIER_CC4IE,
TIM_DIER_CC1IE,// timer 14
TIM_DIER_CC1IE,
TIM_DIER_UIE,
TIM_DIER_CC1IE,// timer 16
TIM_DIER_BIE,
TIM_DIER_COMIE,
TIM_DIER_CC1IE,
TIM_DIER_UIE,
TIM_DIER_CC1IE,// timer 17
TIM_DIER_BIE,
TIM_DIER_COMIE,
TIM_DIER_CC1IE,
TIM_DIER_UIE
};
#define BASE ((TIM_TypeDef *)timerBase_Addr_List[timer])
void timerReset(timerNo_t timer)
{
@ -67,7 +20,7 @@ void timerActivateBus(timerNo_t timer)
if(timerBus_No[timer]==1)
{
RCC->APB1ENR |= (1<<timerBus_En_bitPos[timer]);
return;
return;
}
RCC->APB2ENR |= (1<<timerBus_En_bitPos[timer]);
}
@ -91,6 +44,7 @@ void timerSetCountDirection(timerNo_t timer, timerCountDirection_t direction)
{
if(direction == upCounting)
{
BASE->CR1 &=~ TIM_CR1_DIR;
return;
}
@ -266,7 +220,7 @@ void timerSetPs(timerNo_t timer, uint16_t ps)
}
void timerStart(timerNo_t timer)
void timerSart(timerNo_t timer)
{
timerEnable(timer);
}
@ -288,93 +242,9 @@ uint32_t timerGetCount(timerNo_t timer)
return BASE->CNT;
}
void timerEnableInterrupt(
timerNo_t timer,
intrType_t timerInterrupt)
{
// check for the correct interrupt index
if(timerInterrupt < TIM1_BREAK) return;
if(timerInterrupt > TIM17_UPDATE) return;
// set the corresponding bit in the corresponding timers DIER register
BASE->DIER |= DIER_list[timerInterrupt - TIM1_BREAK];
}
void timerDissableInterrupt(
timerNo_t timer,
intrType_t timerInterrupt)
{
// check for the correct interrupt index
if(timerInterrupt < TIM1_BREAK) return;
if(timerInterrupt >TIM17_UPDATE) return;
// set the corresponding bit in the corresponding timers DIER register
BASE->DIER &= ~DIER_list[timerInterrupt - TIM1_BREAK];
}
void timerThrowError(timerError_t error)
{
while(1);
}
// Interrupt service routines
void TIM1_BRK_UP_TRG_COM_IRQHandler()
{
HANDLE_INT_FLAG(TIM1->SR,TIM_SR_BIF,TIM1_BREAK);
HANDLE_INT_FLAG(TIM1->SR,TIM_SR_UIF,TIM1_UPDATE);
HANDLE_INT_FLAG(TIM1->SR,TIM_SR_TIF,TIM1_TRIGGER);
HANDLE_INT_FLAG(TIM1->SR,TIM_SR_COMIF,TIM1_COMMUNICATION);
}
void TIM1_CC_IRQHandler()
{
HANDLE_INT_FLAG(TIM1->SR,TIM_SR_CC1IF,TIM1_COUNTERCOMPARE_1);
HANDLE_INT_FLAG(TIM1->SR,TIM_SR_CC2IF,TIM1_COUNTERCOMPARE_2);
HANDLE_INT_FLAG(TIM1->SR,TIM_SR_CC3IF,TIM1_COUNTERCOMPARE_3);
HANDLE_INT_FLAG(TIM1->SR,TIM_SR_CC4IF,TIM1_COUNTERCOMPARE_4);
}
void TIM2_IRQHandler()
{
HANDLE_INT_FLAG(TIM2->SR,TIM_SR_UIF,TIM2_UPDATE);
HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC1IF,TIM2_COUNTERCOMPARE_1);
HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC2IF,TIM2_COUNTERCOMPARE_2);
HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC3IF,TIM2_COUNTERCOMPARE_3);
HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC4IF,TIM2_COUNTERCOMPARE_4);
HANDLE_INT_FLAG(TIM2->SR,TIM_SR_TIF,TIM2_TRIGGER);
HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC1OF,TIM2_CAPTURECOMPARE_1);
HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC2OF,TIM2_CAPTURECOMPARE_2);
HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC3OF,TIM2_CAPTURECOMPARE_3);
HANDLE_INT_FLAG(TIM2->SR,TIM_SR_CC4OF,TIM2_CAPTURECOMAPRE_4);
}
void TIM3_IRQHandler()
{
HANDLE_INT_FLAG(TIM3->SR,TIM_SR_UIF,TIM3_UPDATE);
HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC1IF,TIM3_COUNTERCOMPARE_1);
HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC2IF,TIM3_COUNTERCOMPARE_2);
HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC3IF,TIM3_COUNTERCOMPARE_3);
HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC4IF,TIM3_COUNTERCOMPARE_4);
HANDLE_INT_FLAG(TIM3->SR,TIM_SR_TIF,TIM3_TRIGGER);
HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC1OF,TIM3_CAPTURECOMPARE_1);
HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC2OF,TIM3_CAPTURECOMPARE_2);
HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC3OF,TIM3_CAPTURECOMPARE_3);
HANDLE_INT_FLAG(TIM3->SR,TIM_SR_CC4OF,TIM3_CAPTURECOMAPRE_4);
}
void TIM16_IRQHandler()
{
HANDLE_INT_FLAG(TIM16->SR,TIM_SR_CC1OF,TIM16_CAPTURECOMPARE_1_OVERCAPTURE);
HANDLE_INT_FLAG(TIM16->SR,TIM_SR_BIF,TIM16_BREAK);
HANDLE_INT_FLAG(TIM16->SR,TIM_SR_COMIF,TIM16_COMMUNICATION);
HANDLE_INT_FLAG(TIM16->SR,TIM_SR_CC1IF,TIM16_CAPTURECOMPARE_1);
HANDLE_INT_FLAG(TIM16->SR,TIM_SR_UIF,TIM16_UPDATE);
}
void TIM17_IRQHandler()
{
HANDLE_INT_FLAG(TIM17->SR,TIM_SR_CC1OF,TIM17_CAPTURECOMPARE_1_OVERCAPTURE);
HANDLE_INT_FLAG(TIM17->SR,TIM_SR_BIF,TIM17_BREAK);
HANDLE_INT_FLAG(TIM17->SR,TIM_SR_COMIF,TIM17_COMMUNICATION);
HANDLE_INT_FLAG(TIM17->SR,TIM_SR_CC1IF,TIM17_CAPTURECOMPARE_1);
HANDLE_INT_FLAG(TIM17->SR,TIM_SR_UIF,TIM17_UPDATE);
}

@ -1,3 +1,9 @@
####################################################################################################
# bsl_nucleo_f042k6.cmake
####################################################################################################
set(CPU_MCU "-mcpu=cortex-m0")
####################################################################################################
#PROJECT & LIBRARIES : defined by user and important that it comes after the VARIABLES otherwise the Set varibale will not be used.
####################################################################################################
@ -6,24 +12,19 @@ set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_CROSSCOMPILING TRUE)
set(LINKER ${CMAKE_SOURCE_DIR}/csl/stm32f042/startup/STM32F042K6Tx_FLASH.ld)
set(CSL_USED ${CMAKE_SOURCE_DIR}/csl/stm32f042)
####################################################################################################
#VARIABLES : defined by user
####################################################################################################
# Set the required Startup Code
set(STARTUP_CODE ${CSL_STARTUP_DIR}/startup_stm32f042x6.s)
# Defines the linker to be used
set(LINKER ${CSL_STARTUP_DIR}/STM32F042K6Tx_FLASH.ld)
set(CSL_INCLUDES
${UTILS_DIR}
${CMAKE_SOURCE_DIR}/csl/stm32f042/CMSIS/Include
${CMAKE_SOURCE_DIR}/csl/stm32f042/Device)
# Defines The MCU CORE
set(CPU_MCU "-mcpu=cortex-m0")
####################################################################################################
# MAIN COMPILING FLAGS
####################################################################################################
# For flags please check https://manned.org/arm-none-eabi-gcc/34fd6095
set(MAIN_FLAGS
set(C_FLAGS
${CPU_MCU}
-mthumb #Instruction set : https://stackoverflow.com/questions/10638130/what-is-the-arm-thumb-instruction-set
## -O1
@ -33,10 +34,7 @@ set(MAIN_FLAGS
-ffunction-sections #Optimization : used with -fdata-sections
$<$<CONFIG:Debug>:-O -g -gdwarf-2>)
####################################################################################################
# DEFINITIONS
####################################################################################################
set(MAIN_DEFS
set(C_DEFS
-DARM_MCU #Defined by kerem to auto configure headers in main.hpp
-DUSE_FULL_LL_DRIVER
-DSTM32F042x6
@ -51,10 +49,7 @@ set(MAIN_DEFS
-DINSTRUCTION_CACHE_ENABLE=0
-DDATA_CACHE_ENABLE=0)
####################################################################################################
# LINKER FLAGS
####################################################################################################
#The order is important
set(LINKER_FLAGS
${CPU_MCU}
-mthumb
@ -65,18 +60,19 @@ set(LINKER_FLAGS
-lnosys
-Wl,-Map=${PROJECT_NAME}.map,--cref
-Wl,--gc-sections)
#The order is important
####################################################################################################
# Creation of the startup library : Use only needs to chnage the definitions made at the beginning
####################################################################################################
# Sartup can and will most propably require some extra flags
set(STARTUP_FLAGS -x assembler-with-cpp ${MAIN_FLAGS})
# Defines should be the same as the other sources but somes extras could be added if needed
set(STARTUP_DEFS ${MAIN_DEFS})
set (MAIN_INCLUDES ${CMAKE_SOURCE_DIR})
set (MAIN_FLAGS ${C_FLAGS})
set (MAIN_DEFS ${C_DEFS})
add_library(startup ${STARTUP_CODE})
target_compile_options(startup PRIVATE ${STARTUP_FLAGS})
target_compile_definitions(startup PRIVATE ${STARTUP_DEFS})
add_library(sub::startup ALIAS startup)
set(STARTUP_UCODE sub::startup)
list(APPEND EXTRA_LIBS sub::startup)
list(APPEND EXTRA_LIBS sub::delay)
list(APPEND EXTRA_LIBS sub::usart)
list(APPEND EXTRA_LIBS sub::timer)
list(APPEND EXTRA_LIBS sub::init)
list(APPEND EXTRA_LIBS sub::max7219)
list(APPEND EXTRA_LIBS sub::spi)
list(APPEND EXTRA_LIBS sub::i2c)
list(APPEND EXTRA_LIBS sub::pin)
list(APPEND EXTRA LIBS sub::interrupt)

@ -0,0 +1,13 @@
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})

@ -185,3 +185,5 @@ SECTIONS
.ARM.attributes 0 : { *(.ARM.attributes) }
}

@ -0,0 +1,2 @@
add_subdirectory(max7219)
add_subdirectory(max31865)

@ -0,0 +1,5 @@
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)

@ -0,0 +1,5 @@
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)

@ -0,0 +1,52 @@
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)
add_library(INTERRUPT ${CSL_SOURCES}/imp_interrupt.c)
target_compile_options(INTERRUPT PRIVATE ${C_FLAGS})
target_compile_definitions(INTERRUPT PRIVATE ${C_DEFS})
target_include_directories(INTERRUPT PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
add_library(sub::interrupt ALIAS INTERRUPT)

183
env/periferals/i2c.c vendored

@ -0,0 +1,183 @@
#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;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save