Compare commits

...

102 Commits

Author SHA1 Message Date
Kerem Yollu 52f7a1b807 added some notes
2 years ago
Kerem Yollu 69d109582c Compilation order chnaged for the submodules otherwise extra project source files can t reach functions declared in KED
2 years ago
Kerem Yollu 7090e7f925 Issue with the interrupt tables, whnr GPIO is working Timers stop Working and vice versa, the indexing has ome issues
2 years ago
Kerem Yollu 67d67dbfef Double declaration if PINX6_BOTH_EDGE corrected
2 years ago
Kerem Yollu e3c1298f55 Started working on pin interrupt, working example on main.c. transfering it to pin.c
2 years ago
kerem yollu bbb2fefe71 Made some minor chnages to HANDLE_INT_FLAG macro, The fact that Interrups are not functioning correcly after a soft reset is known, chnages in the satrup and to the hardware may alter this behaviour
2 years ago
kerem yollu 68de79e685 Interrupts only Working if a hardware reset is made, There is propably an issue with the interrupt initialization or flag management. table size in imp_timer.c was too small
2 years ago
polymurph 5e4725ef7b started work on interrupts for spi
2 years ago
polymurph b6bbacfffa added adapted timer 2 interrupt
2 years ago
polymurph 217fd76bdb added timer interrupt enable / dissable
2 years ago
polymurph 6d0ffa4045 working on adding timer interrupt enable/dissable feature which sets the DIER register internaly
2 years ago
polymurph 42ef82eb87 added working blinki example
2 years ago
polymurph a97b1885f5 working interrupt handler list with makro for handling the interrupt flags inside the ISR
2 years ago
Kerem Yollu 157d3f61ad Compiling for Interrupt
2 years ago
polymurph 7aa6c00004 added timer 2 blinki example
2 years ago
polymurph 93b8c69102 moved interrupt from peripherals to system
2 years ago
polymurph 782bcdbb2b added missing interrupt headers
2 years ago
polymurph 147c8c7e4b replaced bulky code with makro inside the IRQ Handlers
2 years ago
polymurph 3a2757b390 added makro timer int flag handling makro. NEEDS TO BE TESTED!!!
2 years ago
polymurph 5524efc144 resolved makro errors
2 years ago
polymurph 104eefab3f resolving makro errors
2 years ago
polymurph 1d36ae2336 resolving makro errors
2 years ago
polymurph 14f9913614 resolving makro errors
2 years ago
polymurph 3c95c4c91f resolving makro errors
2 years ago
polymurph 9bc587c0f2 resolving makro errors
2 years ago
polymurph 23b2750e18 created HANDLE_INT_FLAG makro
2 years ago
polymurph 53c87c9cf9 typo in IRQ Handlers
2 years ago
polymurph 70f2035c2c iplemented all timer interrupts
2 years ago
polymurph db1166e1b9 working on timer interrupts
2 years ago
kerem yollu 406bb83fca Defined new todos, and re-aranged timer2 Interrupt
2 years ago
polymurph e6b8b1184d typo in readme ;)
2 years ago
polymurph 9f72f55811 added datasheet
2 years ago
Kerem Yollu 5622103817 Changed the projectDefinitions.cmake to it's final form and corrected the header include issues
2 years ago
Kerem Yollu e14f8b06aa Project submodule generator will indicate if a header wiht the same name of the source exist. changed projectDefinitions.cmake please copy the one in ked/libraries/examples/autoInit
2 years ago
kerem yollu a83a21d7f3 Simplified the projectDefinition.cmake and separated cmakeCore and cmakeProject
2 years ago
kerem yollu 9fb6a9fcb3 I will soon womit CMAKE but its taking ever more shape, if we finr an implmentation without header it wil generate an fatal error, now i will implement a check to find out if two source file or two header files have the same name
2 years ago
kerem yollu 36be0a0f9e Cmake's main functionalities are fully implmeneted now the error handler should be optimized
2 years ago
Kerem Yollu c893a9584e Restructuration from CMakeCore with Edwin Stage 1
2 years ago
Kerem Yollu 8471df9e9c added TODO inside CMakeLists.cmake + coments cleanup
2 years ago
Kerem Yollu 5b8f0a88db added TODO inside CMakeLists.cmake + coments cleanup
2 years ago
kerem yollu 8300246f15 Cmake is taking it final shape, removed the CMakeConfig.txt from stm32f042k6t6 and also from the startup folder | i2c.c -> i2c_init Function has been canged to accep the i2cType only, this saves memory
2 years ago
Kerem Yollu ecca9af3a3 README for driver written and on looking how it presents itself
2 years ago
Kerem Yollu 92f753bf50 Test again for doc
2 years ago
Kerem Yollu f05462067d Added some readme Files
2 years ago
Kerem Yollu fa830512d7 Changed gitignore to ingore the correct htlm and latex files generated by doxygen
2 years ago
Kerem Yollu 3db8bd4052 Continuing on cmake restructuration also added some tweaks to doxygen
2 years ago
kerem yollu 9468fa8622 Reorganizing the Header Structures
2 years ago
kerem yollu fc914ab7db Renaming the varibale in CMAKE so that rthey make more sense
2 years ago
kerem yollu 21f7ecfeb1 New organisation with ./ked/run.sh stm32f042k6t6 is now wokring
2 years ago
kerem yollu 5de8884257 Started the cleaning process, unsuled LCD functions are deleted
2 years ago
polymurph 5e21945627 removed faulty #include
2 years ago
polymurph 409349c3d4 work on interrupts
2 years ago
polymurph 9233133f35 work on interrupts
2 years ago
polymurph d8b89e8564 work on README.md
2 years ago
polymurph 8d8f53e3e5 renamed the folders src to implementation and Device to hardwaerDescription as these names are more descriptiv of what the purpouse is
2 years ago
polymurph 2eab53cb47 work on README.md
2 years ago
polymurph 7591635fc7 work on hwd
2 years ago
polymurph 830b48f9ff work on restructuring to hwd_xxx.h
2 years ago
polymurph 58e472b702 added specific target devidce. Te chip on the NUCLEOF042K6 has the stm32f042k6t6 chip used
2 years ago
polymurph 92418aa4d6 started with splitting up hardwareDescription.hintop individual hwd_xxx.h files
2 years ago
polymurph bbdb0a5ffd cleanup
2 years ago
polymurph 8c86c79533 removed mistake
2 years ago
polymurph 09ac07b25a added missing interrupt stuff in pin.h
2 years ago
polymurph a25938a9a7 missing hardware description for interrupts
2 years ago
polymurph b042b229f9 added interrupt files
2 years ago
kerem yollu 8c1400a53c PLaying around with function pointers
2 years ago
Kerem Yollu e1487d6bb2 Started to reoganise and some test with function pointers in libraries folder
2 years ago
kerem yollu 3e98c7ce71 Finished the basic functions for the lcd like print pixel, chat, test, line, rectangle, circle, now need to clean ssd1306_i2c
2 years ago
kerem yollu d1a570b8df more advancement on the lcd_oled.c and ssd1306.c more functions have been ported and drwa line is working
2 years ago
Kerem Yollu f330f8fe9a lcd_oled.c ans ssd1306_i2c.c is taking shape, now the initialisation functions are made and we cna call lcd_oled_draw_pixel() and lcd_oled_print_char()
2 years ago
Kerem Yollu 13dc881419 Started on the implmentation of my own ssd1306 function that will be later called by lcd_oled.c and fixed wet another Cmake issue where one driver wasn't able to get the header of another driver
2 years ago
kerem yollu 855cd7c99d started with the lcd_oled.h library, and tested the draw pixel command, it works for the example main.c main.h and cmake config please go in /dev/examples
2 years ago
kerem yollu ec87722338 Removed the not needed waitMs() and added a print char command for the oled display
2 years ago
kerem yollu 6814afa6de Run.sh Modified to be able to install stlink from STM
2 years ago
kerem yollu 3ebdf34db2 Sarted testing the i2c library wiht the 0.9Inc oled display, and it is working! just need to to the reset manually
2 years ago
Kerem Yollu 4030ed9611 i2c is working beter and added a check device funtion who checks is a device is on the bu or not. Driver header in cmake were not correctly included, i have fixed that issue too
2 years ago
Kerem Yollu 0e22b6b379 new i2c.c is working but not optimal nad there are some questions concerning the datasheet (NBYTE counter)
2 years ago
Kerem Yollu 0ecc6496af new i2c.c Structure with working read function (polling)
2 years ago
Kerem Yollu fb58ceb58f Working on i2c again making it simpler to use master write doesn't work
2 years ago
Kerem Yollu 0868b65918 Strated to modify the README.md
2 years ago
Kerem Yollu 168136a2f9 Sarted to have look on ked.py and made some commments
2 years ago
polymurph 8bfe9b9021 removed debug prints at the beginning
2 years ago
polymurph 3291ccd8bc working on correct path joining with os
2 years ago
polymurph b766e50abe working on correct path joining with os
2 years ago
polymurph ad4e8d408f working on flasher
2 years ago
polymurph 0a29c368cb added __pycache__/ to .gitignore
2 years ago
polymurph b6a6940de0 working on flashing script
2 years ago
polymurph ccd144c359 work on KED Script
2 years ago
polymurph 3186e3fd64 started work on python KED builder script for use on linux or windows
2 years ago
polymurph ab066f9da6 cleaned up documentation of CMakeLists.txt for readability on one screen
2 years ago
Kerem Yollu 5ef339c5bb Moved library generation functions and driver generation function in to cmakeCore.cmake todo : give the project path trought run.sh the "../" can be confusing
2 years ago
Kerem Yollu fce1f42f88 added error handling changed periferals/ to peripherals/ changed ked/config/ to ked/cmake_core/ moved functions to cmakeCore.cmake
2 years ago
Kerem Yollu c762a4abbd Channged .c extention on library generation function with a PL varibale for future proofing the code
2 years ago
Kerem Yollu 6a4ec9adcf Automated the project configuration file. I need now to moove all the auto include funtions in one file
2 years ago
Kerem Yollu 00a6e0c8e7 Automated the driver library creation and inclusion process for the main Cmake
2 years ago
key 6e6f4f887c Project Configuration made on the same level as main.c and the user should define the folder wehre his headers an sources are. (sources are not getting linked for the moment only headers)
2 years ago
key abddc87d29 Made a list name GENERATED_LIBRARIES whic assmenble The startup uCode, drivers and peripherals together to simplify compilation code
2 years ago
key d8007fb1e3 Libraries are now generated automatically, Startup, Driver and Peripherals have now their own declaration listsa and corresponding librabiries list
2 years ago
Kerem Yollu 7e777c575a Transporting functions for peripherals
2 years ago
Kerem Yollu 9a090f4769 Pripheral submoldule creation function is implemted
2 years ago
Kerem Yollu 4493b5f468 Removed the env directory and correccted the main.c chek funtion in run.sh
2 years ago
Kerem Yollu fb0ff98d6e Changed KED to act as a git Submodule
3 years ago

7
.gitignore vendored

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

@ -0,0 +1,272 @@
cmake_minimum_required(VERSION 3.18)
####################################################################################################
# CMAKE Features
####################################################################################################
# do this instead of declaring languages in the beginning this WILL prevent loop errors.
project(${CSL_USED} ASM C CXX)
# Defining the executables name
set(EXECUTABLE ${PROJECT_NAME})
####################################################################################################
# NON-VITAL OPTION FOR COMPILATION
####################################################################################################
set(CMAKE_VERBOSE_MAKEFILE OFF) # Should CMake print everythign ?
set(OUTPUT_DOXYGEN FALSE) # Should CMake generate Doxygen output ?
set(DOXYGEN_OUTPUT_DIR ${CMAKE_SOURCE_DIR}/env/doc)
# TODO: discuss on where doxygen should place the output
# -> in env/doc
# -> in ked_build outside of the ked environment (prefered, as it includes also the users
# project documentation
# idea -> creakte an override option in the projectConfig.cmake file to be able to define
# where and waht.
set(PL "c") # Used programming language, we could maybe do a check.
####################################################################################################
# PASSED VARIABLE WHEN CALLING run.sh
####################################################################################################
# CSL_USED passed by run.sh and is the quivalent of the ic name
# PROJECT_DIR Passed by run.sh and is the defined place where the project is. run.sh should be in
# the future capable of definin project paht.
####################################################################################################
# Setting the used directory locations
####################################################################################################
# Location of the project : It is defaulted to one Higher than the KED Directory :TODO: Shall we let
set(PROJECT_CONFIG_FILE ${PROJECT_DIR}/projectDefinitions.cmake)
# Location of the cmkae core funtionalities / funtions / definitions
set(CMAKE_CORE_DIR ${CMAKE_SOURCE_DIR}/env/cmake_core)
set(COMPILER_DEFS ${CMAKE_CORE_DIR}/compiler.cmake)
# Location of CSL, CSL_USED is passed as an argument to CMake from run.sh
# -> "Specific to each CSL"
set(CSL_DIR ${CMAKE_SOURCE_DIR}/csl/${CSL_USED})
set(CSL_CONFIG_FILE ${CSL_DIR}/config.cmake)
# To Put one layer down so that CMSIS is defined by the CSL it's core specific stuff
set(CSL_SOURCES_DIR ${CSL_DIR}/implementation)
set(CSL_HEADERS_DIR ${CSL_DIR}/CMSIS/Include ${CSL_DIR}/HardwareDescription)
set(CSL_STARTUP_DIR ${CSL_DIR}/startup)
####################################################################################
# Directiry fot the drivers -> "Common to all CSL"
set(DRIVERS_DIR ${CMAKE_SOURCE_DIR}/drivers)
set(DRIVERS_HEADERS_DIR) #Declared empty because it will be filled automaticaly afterwards
# Directory fot the peripherals -> "Common to all CSL"
set(PERIPHERALS_DIR ${CMAKE_SOURCE_DIR}/peripherals)
set(PERIPHERALS_HEADERS_DIR)#Declared empty because it will be filled automaticaly afterwards
set(PERIPHERAL_LIBS)#Declared empty because it will be filled automaticaly afterwards
# Directory for the libraries -> "Common to all CSL"
set(LIBRARIES_DIR ${CMAKE_SOURCE_DIR}/libraries)
set(LIBRARIES_HEADERS_DIR)#Declared empty because it will be filled automaticaly afterwards
set(LIBRARIES_LIBS)#Declared empty because it will be filled automaticaly afterwards
# Directory for the SYSTEM -> "Common to all CSL"
set(SYSTEM_DIR ${CMAKE_SOURCE_DIR}/system)
set(SYSTEM_HEADERS_DIR)#Declared empty because it will be filled automaticaly afterwards
set(SYSTEM_LIBS)#Declared empty because it will be filled automaticaly afterwards
####################################################################################################
# INCLUDES ####################################################################################################
# Adding human readable color references for cmake
include(${CMAKE_CORE_DIR}/colors.cmake)
# All the library and submodule funtions and definitions are written here
include(${CMAKE_CORE_DIR}/cmakeCore.cmake)
# For Detailed error messages.
include(${CMAKE_CORE_DIR}/errorHandler.cmake)
# For Doxygen document generatio
include(${CMAKE_CORE_DIR}/doxygen.cmake)
# All the library and submodule funtions and definitions are written here
include(${CMAKE_CORE_DIR}/cmakeProject.cmake)
# Include the project definition defined by the end user implementiogn KED as a submodule
include(${PROJECT_CONFIG_FILE})
# Here is the include fopr the awailable peripheral headers and standart libraries.
include(${PERIPHERALS_DIR}/CMakeLists.txt)
# Here is the include fopr the awailable drivers headers and standart libraries.
include(${DRIVERS_DIR}/CMakeLists.txt)
# Here is the include fopr the awailable libraries headers and standart libraries.
include(${LIBRARIES_DIR}/CMakeLists.txt)
# Here is the include fopr the awailable system headers and standart libraries.
include(${SYSTEM_DIR}/CMakeLists.txt)
# Include the config fiel where the compilers to use ar defined
include(${COMPILER_DEFS})
# Confugration file of the csl, there you will wind the starup code handling, compiler/linker
# options, flags and definitions
include(${CSL_CONFIG_FILE})
####################################################################################################
# HEADERS : ALL Header Definitions and calls MUST be made here to be able to propagate them through
# all the modules
####################################################################################################
message("${BoldBlue}")
message("+-------------------------------+")
message("Adding Header Directories")
message("+-------------------------------+")
message("|-->For System")
createHeaderDirList("${SYSTEM_DIR}" "${SYSTEM_LIST}" "SYSTEM_HEADERS_DIR")
message("${BoldBlue}|-->For Peripherals")
createHeaderDirList("${PERIPHERALS_DIR}" "${PERIPHERALS_LIST}" "PERIPHERALS_HEADERS_DIR")
message("${BoldBlue}|-->For Drivers")
createHeaderDirList("${DRIVERS_DIR}" "${DRIVERS_LIST}" "DRIVERS_HEADERS_DIR")
message("${BoldBlue}|-->For Libraries")
createHeaderDirList("${LIBRARIES_DIR}" "${LIBRARIES_LIST}" "LIBRARIES_HEADERS_DIR")
message("${BoldBlue}|-->For Project")
createHeaderDirListProject("${PROJECT_ADDITIONAL_DIRS}" "PROJECT_HEADERS_DIR")
message("${BoldBlue}+-------------------------------+${ColourReset}")
#Stick all the herade direcotries together for ease of use further down
set (COMMON_HEADERS ${CSL_HEADERS_DIR}
${SYSTEM_HEADERS_DIR}
${PERIPHERALS_HEADERS_DIR}
${DRIVERS_HEADERS_DIR}
${LIBRARIES_HEADERS_DIR}
${PROJECT_HEADERS_DIR})
####################################################################################################
# Making Modules
####################################################################################################
message("${BoldBlue}")
message("+-------------------------------+")
message("Making Submolues")
message("+-------------------------------+")
message("|-->For System")
makeSubmodules("${SYSTEM_DIR}" "${SYSTEM_LIST}" "SYSTEM_LIBS")
message("${BoldBlue}|-->For Peripherals")
makeSubmodules("${PERIPHERALS_DIR}" "${PERIPHERALS_LIST}" "PERIPHERAL_LIBS")
message("${BoldBlue}|-->For Drivers")
makeSubmodules("${DRIVERS_DIR}" "${DRIVERS_LIST}" "DRIVER_LIBS")
message("${BoldBlue}|-->For Libraries")
makeSubmodules("${LIBRARIES_DIR}" "${LIBRARIES_LIST}" "LIBRARIES_LIBS")
message("${BoldBlue}|-->For Project")
makeSubmodulesProject("${PROJECT_ADDITIONAL_DIRS}" "${PROJECT_TO_COMPILE_LIST}" "PROJECT_LIBS")
message("${BoldBlue}+-------------------------------+${ColourReset}")
# Stick All the libraries together, only for code redability futher down.
set(GENERATED_LIBRARIES ${PROJECT_LIBS}
${STARTUP_UCODE}
${SYSTEM_LIBS}
${PERIPHERAL_LIBS}
${DRIVER_LIBS}
${LIBRARIES_LIBS})
####################################################################################################
# Overview
####################################################################################################
message("${BoldBlue}")
message("+-------------------------------+")
message("Project Info")
message("+-------------------------------+")
message(" |--> Executable Name:${BoldCyan} ${EXECUTABLE} ${BoldBlue}")
message(" |--> Startup uCode :${BoldCyan} ${STARTUP_CODE} ${BoldBlue}")
message(" |--> Linker :${BoldCyan} ${LINKER} ${BoldBlue}")
message(" |--> Project Dir :${BoldCyan} ${PROJECT_DIR} ${BoldBlue}")
message(" |--> Project Config :${BoldCyan} ${PROJECT_CONFIG_FILE} ${BoldBlue}")
message(" |--> CSL Dir :${BoldCyan} ${CSL_DIR} ${BoldBlue}")
message(" |--> CSL Config :${BoldCyan} ${CSL_CONFIG_FILE} ${BoldBlue}")
message(" |--> Compiler Config:${BoldCyan} ${COMPILER_DEFS} ${BoldBlue}")
message("${BoldBlue}")
message("+-------------------------------+")
message("Compiling Info")
message("+-------------------------------+")
message("|--> Main Compile Definitions:")
printList("${BoldCyan} | " "${MAIN_DEFS}")
message("${BoldBlue}|--> Main Compile Flags:")
printList("${BoldCyan} | " "${MAIN_FLAGS}")
message("${BoldBlue}|--> Linker Flags:")
printList("${BoldCyan} | " "${LINKER_FLAGS}")
message("${BoldBlue}|--> Periferals which will be implemented:")
printList("${BoldCyan} |-> " "${PERIPHERALS_LIST}")
message("${BoldBlue}|--> Drivers which will be implemented:")
printList("${BoldCyan} |-> " "${DRIVERS_LIST}")
message("${BoldBlue}|--> Project sources to be implemented:")
printList("${BoldCyan} |-> " "${PROJECT_TO_COMPILE_LIST}")
message("${BoldBlue}|--> Generated Library Submodules ${Red}!!!The Order Matters!!!${ColourReset}${BoldCyan}")
printList("${BoldCyan} |-> " "${GENERATED_LIBRARIES}")
message("${BoldBlue}+-------------------------------+${ColourReset}")
####################################################################################################
# EXECUTABLE
####################################################################################################
add_executable(${EXECUTABLE} ${PROJECT_DIR}/main.${PL})
target_compile_options(${EXECUTABLE} PRIVATE ${MAIN_FLAGS})
target_compile_definitions(${EXECUTABLE} PRIVATE ${MAIN_DEFS})
target_include_directories(${EXECUTABLE} PUBLIC ${COMMON_HEADERS})
####################################################################################################
# LINKING EXECUTEABLE
####################################################################################################
message("${BoldGreen}")
message("+-------------------------------+")
message("Linker & Compiler Info")
message("+-------------------------------+")
if(IS_NO_SYS)
target_link_libraries(${EXECUTABLE} ${GENERATED_LIBRARIES})
target_link_options(${EXECUTABLE} PRIVATE ${LINKER_FLAGS})
else ()
target_link_libraries(${EXECUTABLE} ${GENERATED_LIBRARIES})
endif()
message(" |-> LINKER : ${LINKER}")
message(" |-> C_COMPILER : ${CMAKE_C_COMPILER}")
message(" |-> CXX_COMPILER: ${CMAKE_CXX_COMPILER}")
message(" |-> ASM_COMPILER: ${CMAKE_ASM_COMPILER}")
message(" |-> OBJCOPY : ${CMAKE_OBJCOPY}")
message(" |-> SIZE : ${CMAKE_SIZE}")
# AS we provide our own linker nad not using the one from the curren OS (system)
message(" |-> LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}")
message("+-------------------------------+")
message("${ColourReset}")
####################################################################################################
# CUSTOM COMMANDS
####################################################################################################
if(NEED_OBJCOPY)
add_custom_command(TARGET ${EXECUTABLE}
POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE} ${PROJECT_NAME}.hex
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE} ${PROJECT_NAME}.bin)
endif()
add_custom_command(TARGET ${EXECUTABLE}
POST_BUILD
COMMAND ${CMAKE_SIZE} ${EXECUTABLE})
####################################################################################################
# Documentation generation
####################################################################################################
generateDoxygen()
####################################################################################################
#CUSTOM Comments from dev.
####################################################################################################
# Link For header dependency : https://stackoverflow.com/questions/11216408/cmake-dependencies-
# headers-between-apps-libraries-in-same-project
# This is one possible trick to handle the assenbly compiling.
# We can't use arm-non-eabi-as because it can onaly hande macros.
# So this bizzare Variable makes shure that whne the asembly compiling is called the -x assembler-
# with-cpp flag is passed
# target_compile_options(${EXECUTABLE} PRIVATE
# $<$<COMPILE_LANGUAGE:ASM>:-x assembler-with-cpp ${ASM_FLAGS}>)

@ -1,19 +1,71 @@
# KED
# KED: Wellcome to Kerem and Edwin's Develeppoment platform.
Kerems and Edwins Develeppoment platform.
08.08.21 Kerem & Edwin
# 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
- 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
## 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.
### 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
@ -65,3 +117,10 @@ 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.

@ -0,0 +1,51 @@
/**
**************************************************************************************************
* @file hardwareDescription.h
* @author Kerem Yollu & Edwin Koch
* @date 19.12.2021
* @version 1.0
**************************************************************************************************
* @brief This file contains all hardware specific definitions for STM32F042K6
*
* **Detailed Description :**
* This Header file contains all the registers and their bit manipulation options.
* All the extra Tables created here are to somplifly the main codes readability
*
* @todo
* - 19.12.2021 : implement until it runs :)
**************************************************************************************************
*/
#ifndef _hardwareDescription_H_
#define _hardwareDescription_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f042x6.h"
#include <stdint.h>
#define PACKAGE_LQFP32 1
#define MAX_I2S_CHANNEL_COUNT 2
#define MAX_CAN_CHANNEL_COUNT 1
/*!
* Enum for awailable clok sources RM Page: 95
* */
typedef enum {
CLK_HSI, /*!< High speed internal */
CLK_HSE, /*!< High speed external */
CLK_LSI, /*!< Low speed internal */
CLK_LSE /*!< Low speed External */
}clkSources_t;
#ifdef __cplusplus
}
#endif
#endif // _hardwareDescription_H_

@ -0,0 +1,56 @@
/**
**************************************************************************************************
* @file hwd_i2c.h
* @author Kerem Yollu & Edwin Koch
* @date 26.02.2023
* @version 1.0
**************************************************************************************************
* @brief
*
* **Detailed Description :**
*
**************************************************************************************************
*/
#ifndef _HWD_I2C_H_
#define _HWD_I2C_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "hardwareDescription.h"
#define MAX_I2C_CHANNEL_COUNT 1
/*! Awailable I2C Channels Hadware dependent Register independent */
typedef enum{
I2C_CH_1
}i2cCh_t;
/*! I2C Channel Base adress Hadware dependent Register dependent*/
static const uint32_t i2cBase_Addr_List[MAX_I2C_CHANNEL_COUNT] = {
I2C1_BASE
};
/*! RCC Bus number index list connected to the I2C */
static const uint8_t i2cBus_No[MAX_I2C_CHANNEL_COUNT] = {
1 /*!< I2C1 is connected to bus 1 */
};
/*! RCC I2C clock enable bit position for the given register*/
static const uint8_t i2cBus_En_bitPos[MAX_I2C_CHANNEL_COUNT] = {
RCC_APB1ENR_I2C1EN_Pos
};
/*! RCC I2C reset bit position for the given register*/
static const uint8_t i2cBus_Rst_bitPos[MAX_I2C_CHANNEL_COUNT] = {
RCC_APB1RSTR_I2C1RST_Pos
};
#ifdef __cplusplus
}
#endif
#endif // _HWD_I2C_H_

@ -0,0 +1,144 @@
/**
**************************************************************************************************
* @file hwd_interrupt.h
* @author Kerem Yollu & Edwin Koch
* @date 26.02.2023
* @version 1.0
**************************************************************************************************
* @brief
*
* **Detailed Description :**
*
**************************************************************************************************
*/
#ifndef _HWD_INTERRUPT_H_
#define _HWD_INTERRUPT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "interrupt.h"
#include "hardwareDescription.h"
/*! interrupt types. These act as indexes for the */
typedef enum {
PINX0_RISING_EDGE,
PINX0_FALLING_EDGE,
PINX0_BOTH_EDGE,
PINX1_RISING_EDGE,
PINX1_FALLING_EDGE,
PINX1_BOTH_EDGE,
PINX2_RISING_EDGE,
PINX2_FALLING_EDGE,
PINX2_BOTH_EDGE,
PINX3_RISING_EDGE,
PINX3_FALLING_EDGE,
PINX3_BOTH_EDGE,
PINX4_RISING_EDGE,
PINX4_FALLING_EDGE,
PINX4_BOTH_EDGE,
PINX5_RISING_EDGE,
PINX5_FALLING_EDGE,
PINX5_BOTH_EDGE,
PINX6_RISING_EDGE,
PINX6_FALLING_EDGE,
PINX6_BOTH_EDGE,
PINX7_RISING_EDGE,
PINX7_FALLING_EDGE,
PINX7_BOTH_EDGE,
PINX8_RISING_EDGE,
PINX8_FALLING_EDGE,
PINX8_BOTH_EDGE,
PINX9_RISING_EDGE,
PINX9_FALLING_EDGE,
PINX9_BOTH_EDGE,
PINX10_RISING_EDGE,
PINX10_FALLING_EDGE,
PINX10_BOTH_EDGE,
PINX11_RISING_EDGE,
PINX11_FALLING_EDGE,
PINX11_BOTH_EDGE,
PINX12_RISING_EDGE,
PINX12_FALLING_EDGE,
PINX12_BOTH_EDGE,
PINX13_RISING_EDGE,
PINX13_FALLING_EDGE,
PINX13_BOTH_EDGE,
PINX14_RISING_EDGE,
PINX14_FALLING_EDGE,
PINX14_BOTH_EDGE,
PINX15_RISING_EDGE,
PINX15_FALLING_EDGE,
PINX15_BOTH_EDGE,
TIM1_BREAK,
TIM1_UPDATE,
TIM1_TRIGGER,
TIM1_COMMUNICATION,
TIM1_COUNTERCOMPARE_1,
TIM1_COUNTERCOMPARE_2,
TIM1_COUNTERCOMPARE_3,
TIM1_COUNTERCOMPARE_4,
TIM2_UPDATE,
TIM2_COUNTERCOMPARE_1,
TIM2_COUNTERCOMPARE_2,
TIM2_COUNTERCOMPARE_3,
TIM2_COUNTERCOMPARE_4,
TIM2_TRIGGER,
TIM2_CAPTURECOMPARE_1,
TIM2_CAPTURECOMPARE_2,
TIM2_CAPTURECOMPARE_3,
TIM2_CAPTURECOMAPRE_4,
TIM3_UPDATE,
TIM3_COUNTERCOMPARE_1,
TIM3_COUNTERCOMPARE_2,
TIM3_COUNTERCOMPARE_3,
TIM3_COUNTERCOMPARE_4,
TIM3_TRIGGER,
TIM3_CAPTURECOMPARE_1,
TIM3_CAPTURECOMPARE_2,
TIM3_CAPTURECOMPARE_3,
TIM3_CAPTURECOMAPRE_4,
TIM14_CAPTURECOMPARE_1_OVERCAPTURE,
TIM14_CAPTURECOMPARE_1,
TIM14_UPDATE,
TIM16_CAPTURECOMPARE_1_OVERCAPTURE,
TIM16_BREAK,
TIM16_COMMUNICATION,
TIM16_CAPTURECOMPARE_1,
TIM16_UPDATE,
TIM17_CAPTURECOMPARE_1_OVERCAPTURE,
TIM17_BREAK,
TIM17_COMMUNICATION,
TIM17_CAPTURECOMPARE_1,
TIM17_UPDATE,
SPI1_TX_FIFO_EMPTY,
SPI1_TX_FIFO_1_4,
SPI1_TX_FIFO_1_2,
SPI1_TX_FIFO_FULL,
SPI1_RX_FIFO_EMPTY,
SPI1_RX_FIFO_1_4,
SPI1_RX_FIFO_1_2,
SPI1_RX_FIFO_FULL,
SPI1_FRAME_FORMAT_ERROR,
SPI1_BUSY,
SPI1_OVERRUN,
SPI1_MODE_FAULT,
SPI1_CRC_ERROR,
SPI1_UNDERRUN,
SPI1_CHANNEL_SIDE,
SPI1_TX_BUFFER_EMPTY,
SPI1_RX_BUFFER_NOT_EMPTY,
intTypeEND
}intrType_t;
#ifdef __cplusplus
}
#endif
#endif // _HWD_INTERRUPT_H_

@ -0,0 +1,138 @@
/**
**************************************************************************************************
* @file hwd_pin.h
* @author Kerem Yollu & Edwin Koch
* @date 26.02.2023
* @version 1.0
**************************************************************************************************
* @brief
*
* **Detailed Description :**
*
**************************************************************************************************
*/
#ifndef _HWD_PIN_H_
#define _HWD_PIN_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "hardwareDescription.h"
#define MAX_N_PORTS_COUNT 3
#define MAX_PORT_PINS_COUNT 16
#define MAX_N_PIN_ALT_FUNC 8
#define MAX_PORT_A_PIN_NO 15
#define MAX_PORT_B_PIN_NO 15
#define MAX_PORT_F_PIN_NO 1
/*! Pin number typedef enum. It contains all the available pins */
typedef enum
{
// NAME = BASE ADDR | PORT | PIN NO
pinA0 = 0x00 | 0, /*!< Port: A Pin: 0 -> Port A Mask | Pin Mask */
pinA1 = 0x00 | 1, /*!< Port: A Pin: 1 -> Port A Mask | Pin Mask */
pinA2 = 0x00 | 2, /*!< Port: A Pin: 2 -> Port A Mask | Pin Mask */
pinA3 = 0x00 | 3, /*!< Port: A Pin: 3 -> Port A Mask | Pin Mask */
pinA4 = 0x00 | 4, /*!< Port: A Pin: 4 -> Port A Mask | Pin Mask */
pinA5 = 0x00 | 5, /*!< Port: A Pin: 5 -> Port A Mask | Pin Mask */
pinA6 = 0x00 | 6, /*!< Port: A Pin: 6 -> Port A Mask | Pin Mask */
pinA7 = 0x00 | 7, /*!< Port: A Pin: 7 -> Port A Mask | Pin Mask */
pinA8 = 0x00 | 8, /*!< Port: A Pin: 8 -> Port A Mask | Pin Mask */
pinA9 = 0x00 | 9, /*!< Port: A Pin: 9 -> Port A Mask | Pin Mask */
pinA10 = 0x00 | 10, /*!< Port: A Pin: 10 -> Port A Mask | Pin Mask */
pinA11 = 0x00 | 11, /*!< Port: A Pin: 11 -> Port A Mask | Pin Mask */
pinA12 = 0x00 | 12, /*!< Port: A Pin: 12 -> Port A Mask | Pin Mask */
pinA13 = 0x00 | 13, /*!< Port: A Pin: 13 -> Port A Mask | Pin Mask */
pinA14 = 0x00 | 14, /*!< Port: A Pin: 14 -> Port A Mask | Pin Mask */
pinA15 = 0x00 | 15, /*!< Port: A Pin: 15 -> Port A Mask | Pin Mask */
pinB0 = 0x10 | 0, /*!< Port: B Pin: 0 -> Port B Mask | Pin Mask */
pinB1 = 0x10 | 1, /*!< Port: B Pin: 1 -> Port B Mask | Pin Mask */
pinB3 = 0x10 | 3, /*!< Port: B Pin: 3 -> Port B Mask | Pin Mask */
pinB4 = 0x10 | 4, /*!< Port: B Pin: 4 -> Port B Mask | Pin Mask */
pinB5 = 0x10 | 5, /*!< Port: B Pin: 5 -> Port B Mask | Pin Mask */
pinB6 = 0x10 | 6, /*!< Port: B Pin: 6 -> Port B Mask | Pin Mask */
pinB7 = 0x10 | 7, /*!< Port: B Pin: 7 -> Port B Mask | Pin Mask */
pinB8 = 0x10 | 8, /*!< Port: B Pin: 8 -> Port B Mask | Pin Mask */
pinF0 = 0x20 | 0, /*!< Port: F Pin: 0 -> Port F Mask | Pin Mask */
pinF1 = 0x20 | 1 /*!< Port: F Pin: 1 -> Port F Mask | Pin Mask */
}pinNo_t;
/*!List of all possible port base addresses. This is used for the funcionality of of pin.h*/
static const uint32_t portBase_Addr_List[MAX_N_PORTS_COUNT] = {
GPIOA_BASE, //!< Base address Port A
GPIOB_BASE, //!< Base address Port B
GPIOF_BASE //!< Base address Port F
};
/*! This is a bitmap list of all possible alternative functions for each pin.
* 1means that there is an alternative function available and 0 for none. Tis is used
* for the functionality in pin.h
* */
static const uint8_t altFunc_List[MAX_N_PORTS_COUNT][MAX_PORT_PINS_COUNT] = {
{ // PORT A
0b01110000, //PA0
0b11110000, //PA1
0b01110000, //PA2
0b01110000, //PA3
0b11111000, //PA4
0b11110000, //PA5
0b11110110, //PA6
0b11111110, //PA7
0b11111000, //PA8
0b01111100, //PA9
0b11111000, //PA10
0b11111100, //PA11
0b11111100, //PA12
0b11100000, //PA13
0b11000000, //PA14
0b11110100 //PA15
},
{ // PORT B
0b11110000, //PB0
0b11110000, //PB1
0b00010000, //PB2
0b11110000, //PB3
0b11110100, //PB4
0b11110000, //PB5
0b11110000, //PB6
0b11110000, //PB7
0b11111000, //PB8
0b11111100, //PB9
0b11110100, //PB10
0b11100000, //PB11
0b11100000, //PB12
0b10100100, //PB13
0b10100100, //PB14
0b10100000 //PB15
},
{ // PORT F
0b11000000, //PF0
0b01000000, //PF1
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000 //N.A
}
};
#ifdef __cplusplus
}
#endif
#endif // _HWD_PIN_H_

@ -0,0 +1,70 @@
/**
**************************************************************************************************
* @file hwd_spi.h
* @author Kerem Yollu & Edwin Koch
* @date 26.02.2023
* @version 1.0
**************************************************************************************************
* @brief
*
* **Detailed Description :**
*
**************************************************************************************************
*/
#ifndef _HWD_SPI_H_
#define _HWD_SPI_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "hardwareDescription.h"
#define MAX_SPI_CHANNEL_COUNT 2
/*!
* RCC Bus number index list connected to the SPI
* */
static const uint8_t spiBus_No[MAX_SPI_CHANNEL_COUNT] = {
2, /*!< SPI 1 is connected to bus 2 */
1 /*!< SPI 2 is connected to bus 1 */
};
/*!
* RCC SPI clock enable bit position for the given register
*
*/
static const uint8_t spiBus_En_bitPos[MAX_SPI_CHANNEL_COUNT] = {
RCC_APB2ENR_SPI1EN_Pos,
RCC_APB1ENR_SPI2EN_Pos
};
/*!
* RCC SPI Reset Bit Position list
* */
static const uint8_t spiBus_Rst_bitPos[MAX_SPI_CHANNEL_COUNT] = {
RCC_APB2RSTR_SPI1RST_Pos,
RCC_APB1RSTR_SPI2RST_Pos
};
/**
* Enumof available spi hardware channels
*/
typedef enum{
SPI_CH_1,
SPI_CH_2
} spiCH_t;
/**
* SPI base address list
*/
static const uint32_t spiBase_Addr_List[MAX_SPI_CHANNEL_COUNT] = {
SPI1_BASE,
SPI2_BASE
};
#ifdef __cplusplus
}
#endif
#endif // _HWD_SPI_H_

@ -0,0 +1,105 @@
/**
**************************************************************************************************
* @file hwd_timer.h
* @author Kerem Yollu & Edwin Koch
* @date 26.02.2023
* @version 1.0
**************************************************************************************************
* @brief
*
* **Detailed Description :**
*
**************************************************************************************************
*/
#ifndef _HWD_TIMER_H_
#define _HWD_TIMER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "hardwareDescription.h"
#define MAX_TIMER_CHANNEL_COUNT 6
/*!
* Enum for awailable timer DS Page: 12 (block diagaram) The order of the enums is very important
* and should not be changed as it is used ofr table indexing
* */
typedef enum {
timer_1, /*!< Advanced control 16-bit timer with PWM capability RM Page: 320 */
timer_2, /*!< General purpose 32-bit timer RM Page: 393 */
timer_3, /*!< General purpose 16-bit timer RM Page: 393 */
timer_14, /*!< General purpose 16-bit timer RM Page: 459 */
timer_16, /*!< General purpose 16-bit timer RM Page: 480 */
timer_17 /*!< General purpose 16-bit timer RM Page: 480 */
} timerNo_t;
/*!
* Timer base addresslist of all available timers
* */
static const uint32_t timerBase_Addr_List[MAX_TIMER_CHANNEL_COUNT] = {
TIM1_BASE, /*!< Timer 1 Base Address */
TIM2_BASE, /*!< Timer 2 Base Address */
TIM3_BASE, /*!< Timer 3 Base Address */
TIM14_BASE, /*!< Timer 14 Base Address */
TIM16_BASE, /*!< Timer 16 Base Address */
TIM17_BASE /*!< Timer 17 Base Address */
};
/*!
* RCC clock enable bit position for the given register
* */
static const uint8_t timerBus_En_bitPos[MAX_TIMER_CHANNEL_COUNT] = {
RCC_APB2ENR_TIM1EN_Pos,
RCC_APB1ENR_TIM2EN_Pos,
RCC_APB1ENR_TIM3EN_Pos,
RCC_APB1ENR_TIM14EN_Pos,
RCC_APB2ENR_TIM16EN_Pos,
RCC_APB2ENR_TIM17EN_Pos
};
/*!
* RCC timer Reset Bit Position list
* */
static const uint8_t timerBus_Rst_bitPos[MAX_TIMER_CHANNEL_COUNT] = {
RCC_APB2RSTR_TIM1RST_Pos,
RCC_APB1RSTR_TIM2RST_Pos,
RCC_APB1RSTR_TIM3RST_Pos,
RCC_APB1RSTR_TIM14RST_Pos,
RCC_APB2RSTR_TIM16RST_Pos,
RCC_APB2RSTR_TIM17RST_Pos
};
/*!
* RCC Bus number index list connected to the timer
* */
static const uint8_t timerBus_No[MAX_TIMER_CHANNEL_COUNT] = {
2, /*!< timer 1 is connected to bus 2 */
1, /*!< timer 2 is connected to bus 1 */
1, /*!< timer 3 is connected to bus 1 */
1, /*!< timer 14 is connected to bus 1 */
2, /*!< timer 16 is connected to bus 2 */
2 /*!< timer 17 is connected to bus 2 */
};
/*!
* Timer Prescaler resolution list TO BE DELETED IF NOT NEEDED
* */
static const uint32_t timerRes_Prescaler[MAX_TIMER_CHANNEL_COUNT] = {
0xFFFF, /*!< Timer 1 Prescaler Max Value */
0xFFFF, /*!< Timer 2 Prescaler Max Value */
0xFFFF, /*!< Timer 3 Prescaler Max Value */
0xFFFF, /*!< Timer 14 Prescaler Max Value */
0xFFFF, /*!< Timer 16 Prescaler Max Value */
0xFFFF, /*!< Timer 17 Prescaler Max Value */
};
#ifdef __cplusplus
}
#endif
#endif // _HWD_TIMER_H_

@ -0,0 +1,30 @@
/**
**************************************************************************************************
* @file hwd_usart.h
* @author Kerem Yollu & Edwin Koch
* @date 26.02.2023
* @version 1.0
**************************************************************************************************
* @brief
*
* **Detailed Description :**
*
**************************************************************************************************
*/
#ifndef _HWD_USART_H_
#define _HWD_USART_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "hardwareDescription.h"
#define MAX_USART_CHANNEL_COUNT 2
#ifdef __cplusplus
}
#endif
#endif // _HWD_USART_H_

@ -1,9 +1,3 @@
####################################################################################################
# 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.
####################################################################################################
@ -12,19 +6,24 @@ 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)
set(CSL_INCLUDES
${UTILS_DIR}
${CMAKE_SOURCE_DIR}/csl/stm32f042/CMSIS/Include
${CMAKE_SOURCE_DIR}/csl/stm32f042/Device)
# Defines the linker to be used
set(LINKER ${CSL_STARTUP_DIR}/STM32F042K6Tx_FLASH.ld)
# 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(C_FLAGS
set(MAIN_FLAGS
${CPU_MCU}
-mthumb #Instruction set : https://stackoverflow.com/questions/10638130/what-is-the-arm-thumb-instruction-set
## -O1
@ -34,7 +33,10 @@ set(C_FLAGS
-ffunction-sections #Optimization : used with -fdata-sections
$<$<CONFIG:Debug>:-O -g -gdwarf-2>)
set(C_DEFS
####################################################################################################
# DEFINITIONS
####################################################################################################
set(MAIN_DEFS
-DARM_MCU #Defined by kerem to auto configure headers in main.hpp
-DUSE_FULL_LL_DRIVER
-DSTM32F042x6
@ -49,7 +51,10 @@ set(C_DEFS
-DINSTRUCTION_CACHE_ENABLE=0
-DDATA_CACHE_ENABLE=0)
####################################################################################################
# LINKER FLAGS
####################################################################################################
#The order is important
set(LINKER_FLAGS
${CPU_MCU}
-mthumb
@ -60,18 +65,18 @@ set(LINKER_FLAGS
-lnosys
-Wl,-Map=${PROJECT_NAME}.map,--cref
-Wl,--gc-sections)
#The order is important
set (MAIN_INCLUDES ${CMAKE_SOURCE_DIR})
set (MAIN_FLAGS ${C_FLAGS})
set (MAIN_DEFS ${C_DEFS})
####################################################################################################
# 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})
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)
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)

@ -1,4 +1,4 @@
#include"deviceSetup.h"
#include "deviceSetup.h"
#include "stm32f042x6.h"
@ -8,6 +8,7 @@
#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
@ -18,6 +19,7 @@ void setupInit()
setupBus();
setupMemory();
setupClock();
__disable_irq();
setupPower();
delayInitMs(SYS_CLK, 1000);
}

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

@ -0,0 +1,153 @@
#include "interrupt.h"
#include "hwd_interrupt.h"
#include "pin.h"
volatile void (*intHandlerArray[intTypeEND])() = {NULL};
const uint8_t interruptTypeIndexList[intTypeEND] =
{
EXTI0_1_IRQn,
EXTI0_1_IRQn,
EXTI0_1_IRQn,
EXTI0_1_IRQn,
EXTI0_1_IRQn,
EXTI2_3_IRQn,
EXTI2_3_IRQn,
EXTI2_3_IRQn,
EXTI2_3_IRQn,
EXTI2_3_IRQn,
EXTI2_3_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
EXTI4_15_IRQn,
TIM1_BRK_UP_TRG_COM_IRQn,
TIM1_BRK_UP_TRG_COM_IRQn,
TIM1_BRK_UP_TRG_COM_IRQn,
TIM1_BRK_UP_TRG_COM_IRQn,
TIM1_CC_IRQn,
TIM1_CC_IRQn,
TIM1_CC_IRQn,
TIM1_CC_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM2_IRQn,
TIM3_IRQn,
TIM3_IRQn,
TIM3_IRQn,
TIM3_IRQn,
TIM3_IRQn,
TIM3_IRQn,
TIM3_IRQn,
TIM3_IRQn,
TIM3_IRQn,
TIM3_IRQn,
TIM14_IRQn,
TIM14_IRQn,
TIM14_IRQn,
TIM16_IRQn,
TIM16_IRQn,
TIM16_IRQn,
TIM16_IRQn,
TIM16_IRQn,
TIM17_IRQn,
TIM17_IRQn,
TIM17_IRQn,
TIM17_IRQn,
TIM17_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn,
SPI1_IRQn
};
void intInit(
intrType_t intType,
intHandler_t handler,
uint8_t priority)
{
// check if index is correct
if(intType >= intTypeEND) return;
intDisableGlobal();
NVIC_SetPriority(interruptTypeIndexList[intType], priority);
intHandlerArray[intType] = handler;
}
void intEnableGlobal()
{
__enable_irq();
}
void intDisableGlobal()
{
__disable_irq();
}
void intEnable(
intrType_t intType)
{
NVIC_EnableIRQ(interruptTypeIndexList[intType]);
}
void intDissable(
intrType_t intType)
{
NVIC_DisableIRQ(interruptTypeIndexList[intType]);
}

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

@ -1,5 +1,7 @@
#include "spi.h"
#include "hardwareDescription.h"
#include "hwd_spi.h"
#include "interrupt.h"
#define SPI_BASE ((SPI_TypeDef *)spiBase_Addr_List[spi_hw_ch])
@ -145,3 +147,15 @@ 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,7 +1,54 @@
#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!
#define BASE ((TIM_TypeDef *)timerBase_Addr_List[timer])
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
};
void timerReset(timerNo_t timer)
{
@ -20,7 +67,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]);
}
@ -44,7 +91,6 @@ void timerSetCountDirection(timerNo_t timer, timerCountDirection_t direction)
{
if(direction == upCounting)
{
BASE->CR1 &=~ TIM_CR1_DIR;
return;
}
@ -220,7 +266,7 @@ void timerSetPs(timerNo_t timer, uint16_t ps)
}
void timerSart(timerNo_t timer)
void timerStart(timerNo_t timer)
{
timerEnable(timer);
}
@ -242,9 +288,93 @@ 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);
}

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

@ -0,0 +1,96 @@
# Drivers
## Description
Drivers are the higher level of code provided by *KED*. It comes on top of the [Peripherals](https://git.keydev.me/kerem/KED/src/branch/master/peripherals) and alows the usage of comercially awailable IC's or moludes.
---
## Please follow this guide to find out about the :
- [Structure](#structure)
- [Usage](#usage)
- [Creation](#creation)
- [Modification](#modification)
- [Credits](#credits)
- [License](#license)
---
## Structure
##### The __driver__ folder has multiple elements inside :
+ CMakeLists.txt
+ where the DRIVERS_LIST is defined
+ Folders named after the driver that they respresent. Inside you will find:
+ Source file of the driver
+ Header file of the driver
+ This Readme file
---
## Usage
In the *CMakeLists.txt* you will find the decalarion of __DRIVERS_LIST__ list which contains the dirvers that are to be compiled.
The *name* of the declared *driver* also defines the name of the driver's *folder*, *souce* file and *header* file.
Once the driver is implemented correctly you can call the header of the driver from any soure of header file.
> exmaple for *ssd1306_i2c*
~~~ C
#include "ssd1306_i2c.h"
~~~
CMake will the automatically find the driver, compile it and implement it to the main projet as a submodule.
---
## Creation
### Let's implement a driver named *ssd1306_i2c*
#### First let's add *ssd1306_i2c* to the __DRIVERS_LIST__.
Open *CMakeLists.txt* with your favorite *text editor* and modifiy the line wehre __DRIVERS_LIST__ is defined.
In which order the drivers are added to the list has no importance.
> Before adding *ssd1306_i2c*
~~~ CMAKE
set(DRIVERS_LIST lcd_oled max7219 max31865)
~~~
> After adding *ssd1306_i2c* the declaration of __DRIVERS_LIST__ should look like this
~~~ CMAKE
set(DRIVERS_LIST lcd_oled max7219 max31865 ssd1306_i2c)
~~~
#### Than we can create a folder with the same name
~~~ bash
mkdir ssd1306_i2c
~~~
#### Inside the newly created folder add the *source* and *header* file with the same name as the driver
In our case that means __ssd1306_i2c.c__ and __ssd1306_i2c.h__
~~~ bash
touch ssd1306_i2c.c ssd1306_i2c.h
~~~
#### The final structure should look like this
As you can see this folder also contains the datashhed for this driver. If you have any additional documentation like a datasheet or calculation sheet, feel free to add them here.
~~~ bash
└── ssd1306_i2c
├── ssd1306_i2c.c
├── ssd1306_i2c.h
└── SSD1306.pdf
~~~
---
## Modification
You can modify each driver to your convinience but it can't be pushed again so please be careful during GIT transactions.
You can also remove any driver from the complation by simply removing his declaration from the __DRIVERS_LIST__
> Like so :
set(DRIVERS_LIST lcd_oled max7219 max31865 ~~ssd1306_i2c~~)
## How to Contribute
Do you want to become a contibutor ? :
How is Ked organised :
Rules to write a Driver :
## Credits
Edwin Koch
Kerem Yollu
## License
The last section of a high-quality README file is the license. This lets other developers know what they can and cannot do with your project. If you need help choosing a license, refer to [https://choosealicense.com/](https://choosealicense.com/).
---

@ -0,0 +1,357 @@
#include "lcd_oled.h"
#include "ssd1306_i2c.h"
i2c_t i2c_device = { I2C_CH_1, /*!< The harware channel to be used */
i2c_mode_master, /*!< Master Mode */
0x00, /*!< First and Main address of the device */
0x00, /*!< Second address if dual addresse mode is configured */
i2c_address_count_single, /*!< Single address */
i2c_address_size_7b, /*!< 10 or 7 bit address size */
i2c_clk_speed_standart, /*!< Bus Speed: standart */
i2c_clk_stretching_disable, /*!< Clock Streching disabeled */
i2c_wake_disabled}; /*!< Wake up condition : None */
#define pgm_read_byte(addr) (*(const uint8_t *)(addr))
#define ssd1306_swap(a, b) { int16_t t = a; a = b; b = t; }
#define ROTATION 0 // TODO: This shoudl be initiated at the function
uint8_t display_buffer[LCD_OLED_SIZE_X * LCD_OLED_SIZE_Y / 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF,
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84, 0x00, 0x00, 0x80, 0xF8,
0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80,
0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0x01, 0x01,
0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF,
0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7, 0xFF, 0xFF, 0x00, 0x00,
0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x7F, 0xFF,
0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF,
0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x8F,
0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC,
0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x01, 0x03, 0x03, 0x03,
0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01,
0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00,
0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03,
0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x0F,
0x87, 0xC7, 0xF7, 0xFF, 0xFF, 0x1F, 0x1F, 0x3D, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0x7C, 0x7D, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x00, 0x30, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F,
0x0F, 0x07, 0x1F, 0x7F, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xE0,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00,
0x00, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xF0, 0xF8, 0x1C, 0x0E,
0x06, 0x06, 0x06, 0x0C, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFC,
0xFE, 0xFC, 0x00, 0x18, 0x3C, 0x7E, 0x66, 0xE6, 0xCE, 0x84, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x06,
0x06, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xC0, 0xF8,
0xFC, 0x4E, 0x46, 0x46, 0x46, 0x4E, 0x7C, 0x78, 0x40, 0x18, 0x3C, 0x76, 0xE6, 0xCE, 0xCC, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00,
0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x03, 0x07, 0x0E, 0x0C,
0x18, 0x18, 0x0C, 0x06, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0E, 0x0C, 0x18, 0x0C, 0x0F,
0x07, 0x01, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00,
0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x07,
0x07, 0x0C, 0x0C, 0x18, 0x1C, 0x0C, 0x06, 0x06, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void lcd_oled_init(i2c_t *i2c_dev, uint8_t address)
{
i2c_init(&i2c_device);
ssd1306_i2c_set_display_off(i2c_dev);
ssd1306_i2c_set_display_clkDiv_oscFreq(i2c_dev, 0, 15); // Working but to be refined
ssd1306_i2c_set_multiplex_ratio(i2c_dev, LCD_OLED_SIZE_Y - 1); // Pages start at 0 and ends at 63
ssd1306_i2c_set_display_offset(i2c_dev, 0x00); // No Offset
ssd1306_i2c_set_display_start_line(i2c_dev, 0); // Start line 0
ssd1306_i2c_set_chage_pump(i2c_dev, SSD1306_SWITCHCAPVCC);
ssd1306_i2c_set_memory_addressing_mode(i2c_dev, SSD1306_MEMORY_MODE_HORIZONTAL);
ssd1306_i2c_set_segment_remap(i2c_dev, 1);
ssd1306_i2c_set_com_scan_direction(i2c_dev, 0); //Decremental TODO : Make a define for it
ssd1306_i2c_set_com_pins(i2c_dev, SSD1306_COM_SEQ_LR_REMAP_ON);
ssd1306_i2c_set_contrast(i2c_dev,0x9F);
ssd1306_i2c_set_prechage_period(i2c_dev, 0xF0); // TODO : I don't know what he exxect is
ssd1306_i2c_set_com_deselect_level(i2c_dev, 0x40); // TODO : PLeanty of things can influance this capacitor value being the most importnat one
ssd1306_i2c_set_display_entire_on(i2c_dev, SSD1306_DISPLAYALLON_RESUME);
ssd1306_i2c_set_display_invert_pixel(i2c_dev, 0); // Normal pilex printing. Warning this hurts the eye
ssd1306_i2c_set_scroll(i2c_dev, 0);// Turn scrolling off
ssd1306_i2c_set_display_on(i2c_dev);
}
uint8_t lcd_oled_clear()
{
memset(display_buffer, 0,(LCD_OLED_SIZE_X * LCD_OLED_SIZE_Y / 8) * sizeof(uint8_t));
return 1;
}
uint8_t lcd_oled_display()
{
ssd1306_i2c_send_command(&i2c_device,SSD1306_COLUMNADDR);
ssd1306_i2c_send_command(&i2c_device,0); // Column start address (0 = reset)
ssd1306_i2c_send_command(&i2c_device,LCD_OLED_SIZE_X - 1); // Column end address (127
// = reset)
ssd1306_i2c_send_command(&i2c_device,SSD1306_PAGEADDR);
ssd1306_i2c_send_command(&i2c_device,0); // Page start address (0 = reset)
ssd1306_i2c_send_command(&i2c_device,7); // Page end address
uint8_t i2cDataLenght = 1; // Co = 0, D/C = 0
uint16_t address = SSD1306_I2C_ADDRESS; // Co = 0, D/C = 0
uint8_t reg = 0x40;
// I2C
int16_t i;
for (i = 0; i < (LCD_OLED_SIZE_X * SSD1306_LCDHEIGHT / 8); i++) {
i2c_write(&i2c_device, &address, &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);
}
}
}

@ -0,0 +1,78 @@
#ifndef _LCD_OLED_H_
#define _LCD_OLED_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <string.h>
#include "oled_fonts.h"
#define FILLED 1
#define EMPTY 0
#define LCD_OLED_I2C
#define LCD_OLED_SIZE_X 128
#define LCD_OLED_SIZE_Y 64
#if defined LCD_OLED_I2C
#include "i2c.h"
void lcd_oled_init(i2c_t *i2c_dev, uint8_t address);
#elif defined LCD_OLED_SPI
#include "spi.h"
void lcd_oled_init(spi_t *spi_dev, pinNo_t pinNo, uint8_t address);
#else
#error "Please Define The communication Methode in ked/drivers/lcd_oled/lcd_oled.h"
#endif
void lcd_oled_enable();
void lcd_oled_disable();
void lcd_oled_reset_hard();
void lcd_oled_reset_soft();
uint8_t lcd_oled_is_ready();
void lcd_oled_sleep();
void lcd_oled_wake();
void lcd_oled_draw_pixel(uint16_t x, uint16_t y, uint8_t color);
void lcd_oled_draw_line(uint16_t x, uint16_t y, uint16_t angle, uint16_t lenght, uint8_t color);
void lcd_oled_draw_rectangle(uint16_t x, uint16_t y, uint16_t length, uint16_t width, uint8_t fill, uint8_t color);
void lcd_oled_draw_circle(uint16_t x, uint16_t y, uint16_t radius, uint8_t fill, uint8_t color);
void lcd_oled_draw_circle_bresenham(int16_t xc, int16_t yc, uint8_t x, uint8_t y, uint8_t color);
void lcd_oled_scroll_right(uint16_t start, uint16_t stop);
void lcd_oled_scroll_left(uint16_t start, uint16_t stop);
void lcd_oled_scroll_up(uint16_t start, uint16_t stop);
void lcd_oled_scroll_down(uint16_t start, uint16_t stop);
void lcd_oled_set_font(uint8_t *font, uint8_t size, uint8_t spacing);
void lcd_oled_print_char(uint16_t x, uint16_t y, uint8_t c, uint8_t color);
void lcd_oled_print_text(uint16_t x, uint16_t y, uint8_t *text, uint16_t length, uint8_t color);
void lcd_oled_print_cursor(uint8_t blink);
void lcd_oled_goto_pos(uint16_t x, uint16_t y);
uint8_t lcd_oled_display();
uint8_t lcd_oled_clear();
void lcd_oled_change_brightness(uint8_t brightness);
void lcd_oled_change_contrast(uint8_t contrast);
void lcd_oled_rotate(uint8_t angle);
void lcd_oled_inverse(uint8_t yseNo);
void lcd_oled_invert(uint8_t yseNo);
#ifdef __cplusplus
}
#endif
#endif /* _LCD_OLED_H_ */

Binary file not shown.

@ -0,0 +1,287 @@
/*********************************************************************
SSD1306 I2C Library for Raspberry Pi.
Based on Adafruit SSD1306 Arduino library. Some functions came from Adafruit GFX lib
Modified by Ilia Penev
Tested on Raspberry Pi 2 with 0.96 Yellow/Blue OLED
*********************************************************************/
/*********************************************************************
This is a library for our Monochrome OLEDs based on SSD1306 drivers
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/category/63_98
These displays use SPI to communicate, 4 or 5 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen below must be included in any redistribution
*********************************************************************/
#include <stdint.h>
#include <string.h>
#include "ssd1306_i2c.h"
#include "oled_fonts.h"
#include "lcd_oled.h"
#define true 1
#define false 0
#define rotation 0
int8_t cursor_y = 0;
int8_t cursor_x = 0;
int16_t i2cd;
#define ssd1306_swap(a, b) { int16_t t = a; a = b; b = t; }
//Section : 10.1.12 Set Display ON/OFF (AEh/AFh) | Page 37
void ssd1306_i2c_set_display_off(i2c_t *i2c_dev)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_DISPLAYOFF);
}
//Section : 10.1.12 Set Display ON/OFF (AEh/AFh) | Page 37
void ssd1306_i2c_set_display_on(i2c_t *i2c_dev)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_DISPLAYON);
}
// TODO: Find a ferq Calculator
// Section : 10.1.16 Set Display Clock Divide Ratio/ Oscillator Frequency (D5h) | Page : 40
void ssd1306_i2c_set_display_clkDiv_oscFreq(i2c_t *i2c_dev, uint8_t clockDivider, uint8_t oscillatorFreq)
{
uint8_t value = 0;
if(oscillatorFreq <= 15)
{
if(clockDivider <= 16)
{
value = (oscillatorFreq << 4) | clockDivider;
}
}
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
ssd1306_i2c_send_command(i2c_dev,value); // the suggested ratio 0x80
}
// Section : 10.1.11 Set Multiplex Ratio (A8h) | Page : 37
void ssd1306_i2c_set_multiplex_ratio(i2c_t *i2c_dev, uint8_t ratio)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETMULTIPLEX); // 0xA8
ssd1306_i2c_send_command(i2c_dev,ratio);
}
// Section : 10.1.15 Set Display Offset (D3h) | Page : 37
void ssd1306_i2c_set_display_offset(i2c_t *i2c_dev, uint8_t offset)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETDISPLAYOFFSET); // 0xD3
ssd1306_i2c_send_command(i2c_dev,offset);
}
// Section : 10.1.13 Set Page Start Address for Page Addressing Mode (B0h~B7h) | Page : 37
void ssd1306_i2c_set_display_start_line(i2c_t *i2c_dev, uint8_t start)
{
if(start <= 7)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETSTARTLINE | start);
}
}
// TODO : Some things are not clear What does 0x10 do ?
// Section : 2.1 Command Table for Charge Bump Setting | Page : 60
void ssd1306_i2c_set_chage_pump(i2c_t *i2c_dev, uint8_t voltageSource)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_CHARGEPUMP); // 0x8D
if (voltageSource == SSD1306_EXTERNALVCC) {
ssd1306_i2c_send_command(i2c_dev,0x10);
} else {
ssd1306_i2c_send_command(i2c_dev,SSD1306_ENABLE_CHAGE_PUMP);
}
}
// Section :10.1.3 Set Memory Addressing Mode (20h) | Page : 34
void ssd1306_i2c_set_memory_addressing_mode(i2c_t *i2c_dev, uint8_t mode)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_MEMORYMODE);
ssd1306_i2c_send_command(i2c_dev,mode);
}
// TODO : Not very clear what this functionality does :S
// Section : 10.1.8 Set Segment Re-map (A0h/A1h)
void ssd1306_i2c_set_segment_remap(i2c_t *i2c_dev, uint8_t enable)
{
if(enable)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_SEGREMAP | 0x1);
}
else
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_SEGREMAP | 0x0);
}
}
// Section : 10.1.14 Set COM Output Scan Direction (C0h/C8h) | Page 37
void ssd1306_i2c_set_com_scan_direction(i2c_t *i2c_dev, uint8_t incremental)
{
if(incremental)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_COMSCANINC);
}
else
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_COMSCANDEC);
}
}
// Section : 10.1.18 Set COM Pins Hardware Configuration (DAh) | Page : 40
void ssd1306_i2c_set_com_pins(i2c_t *i2c_dev, uint8_t alignment)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETCOMPINS);
ssd1306_i2c_send_command(i2c_dev,alignment);
}
void ssd1306_i2c_set_contrast(i2c_t *i2c_dev, uint8_t contrast)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETCONTRAST); // 0x81
ssd1306_i2c_send_command(i2c_dev,contrast);
}
void ssd1306_i2c_set_prechage_period(i2c_t *i2c_dev, uint8_t period)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETPRECHARGE); // 0xd9
ssd1306_i2c_send_command(i2c_dev,period);
}
void ssd1306_i2c_set_com_deselect_level(i2c_t *i2c_dev, uint8_t voltageLevel)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_SETVCOMDETECT); // 0xDB
ssd1306_i2c_send_command(i2c_dev,voltageLevel);
}
void ssd1306_i2c_set_display_entire_on(i2c_t *i2c_dev, uint8_t resumeOrForce)
{
if(resumeOrForce == SSD1306_DISPLAYALLON_RESUME)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_DISPLAYALLON_RESUME); // 0xA4
}
else
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_DISPLAYALLON); // 0xA4
}
}
void ssd1306_i2c_set_display_invert_pixel(i2c_t *i2c_dev, uint8_t inverted)
{
if(inverted)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_INVERTDISPLAY); // 0xA6
}
else
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_NORMALDISPLAY); // 0xA6
}
}
void ssd1306_i2c_set_scroll(i2c_t *i2c_dev, uint8_t onOff)
{
if(onOff)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
}
else
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_DEACTIVATE_SCROLL);
}
}
void ssd1306_i2c_send_command(i2c_t *i2c_dev,uint8_t c)
{
// I2C
uint8_t control = 0x00; // Co = 0, D/C = 0
uint8_t i2cDataLenght = 1; // Co = 0, D/C = 0
uint16_t address = SSD1306_I2C_ADDRESS; // Co = 0, D/C = 0
i2c_write(i2c_dev, &address, &control, &c, &i2cDataLenght);
}
// startscrollright
// Activate a right handed scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// ssd1306_scrollright(0x00, 0x0F)
void ssd1306_startscrollright(i2c_t *i2c_dev, uint16_t start, uint16_t stop)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_RIGHT_HORIZONTAL_SCROLL);
ssd1306_i2c_send_command(i2c_dev,0X00);
ssd1306_i2c_send_command(i2c_dev,start);
ssd1306_i2c_send_command(i2c_dev,0X00);
ssd1306_i2c_send_command(i2c_dev,stop);
ssd1306_i2c_send_command(i2c_dev,0X00);
ssd1306_i2c_send_command(i2c_dev,0XFF);
ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
}
// startscrollleft
// Activate a right handed scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// ssd1306_scrollright(0x00, 0x0F)
void ssd1306_startscrollleft(i2c_t *i2c_dev,uint16_t start, uint16_t stop)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_LEFT_HORIZONTAL_SCROLL);
ssd1306_i2c_send_command(i2c_dev,0X00);
ssd1306_i2c_send_command(i2c_dev,start);
ssd1306_i2c_send_command(i2c_dev,0X00);
ssd1306_i2c_send_command(i2c_dev,stop);
ssd1306_i2c_send_command(i2c_dev,0X00);
ssd1306_i2c_send_command(i2c_dev,0XFF);
ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
}
// startscrolldiagright
// Activate a diagonal scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// ssd1306_scrollright(0x00, 0x0F)
void ssd1306_startscrolldiagright(i2c_t *i2c_dev, uint16_t start, uint16_t stop)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_SET_VERTICAL_SCROLL_AREA);
ssd1306_i2c_send_command(i2c_dev,0X00);
ssd1306_i2c_send_command(i2c_dev,SSD1306_LCDHEIGHT);
ssd1306_i2c_send_command(i2c_dev,SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL);
ssd1306_i2c_send_command(i2c_dev,0X00);
ssd1306_i2c_send_command(i2c_dev,start);
ssd1306_i2c_send_command(i2c_dev,0X00);
ssd1306_i2c_send_command(i2c_dev,stop);
ssd1306_i2c_send_command(i2c_dev,0X01);
ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
}
// startscrolldiagleft
// Activate a diagonal scroll for rows start through stop
// Hint, the display is 16 rows tall. To scroll the whole display, run:
// ssd1306_scrollright(0x00, 0x0F)
void ssd1306_startscrolldiagleft(i2c_t *i2c_dev, uint16_t start, uint16_t stop)
{
ssd1306_i2c_send_command(i2c_dev,SSD1306_SET_VERTICAL_SCROLL_AREA);
ssd1306_i2c_send_command(i2c_dev,0X00);
ssd1306_i2c_send_command(i2c_dev,SSD1306_LCDHEIGHT);
ssd1306_i2c_send_command(i2c_dev,SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL);
ssd1306_i2c_send_command(i2c_dev,0X00);
ssd1306_i2c_send_command(i2c_dev,start);
ssd1306_i2c_send_command(i2c_dev,0X00);
ssd1306_i2c_send_command(i2c_dev,stop);
ssd1306_i2c_send_command(i2c_dev,0X01);
ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL);
}

@ -0,0 +1,173 @@
/*********************************************************************
SSD1306 I2C Library for Raspberry Pi.
Based on Adafruit SSD1306 Arduino library. Some functions came from Adafruit GFX lib.
Modified by Ilia Penev
Tested on Raspberry Pi 2 with 0.96 Yellow/Blue OLED
*********************************************************************/
/*********************************************************************
This is a library for our Monochrome OLEDs based on SSD1306 drivers
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/category/63_98
These displays use SPI to communicate, 4 or 5 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/
#ifndef SSD1306_I2C_H_
#define SSD1306_I2C_H_
#include "i2c.h"
#define BLACK 0
#define WHITE 1
#define INVERSE 2
#define SSD1306_I2C_ADDRESS 0x3C // 011110+SA0+RW - 0x3C or 0x3D
// Address for 128x32 is 0x3C
// Address for 128x64 is 0x3D (default) or 0x3C (if SA0 is grounded)
/*=========================================================================
SSD1306 Displays
-----------------------------------------------------------------------
The driver is used in multiple displays (128x64, 128x32, etc.).
Select the appropriate display below to create an appropriately
sized framebuffer, etc.
SSD1306_128_64 128x64 pixel display
SSD1306_128_32 128x32 pixel display
SSD1306_96_16
-----------------------------------------------------------------------*/
#define SSD1306_128_64
// #define SSD1306_128_32
// #define SSD1306_96_16
/*=========================================================================*/
#if defined SSD1306_128_32
#define WIDTH 128
#define HEIGHT 32
#endif
#if defined SSD1306_128_64
#define WIDTH 128
#define HEIGHT 64
#endif
#if defined SSD1306_96_16
#define WIDTH 96
#define HEIGHT 16
#endif
#if defined SSD1306_128_64 && defined SSD1306_128_32
#error "Only one SSD1306 display can be specified at once in SSD1306.h"
#endif
#if !defined SSD1306_128_64 && !defined SSD1306_128_32 && !defined SSD1306_96_16
#error "At least one SSD1306 display must be specified in SSD1306.h"
#endif
#if defined SSD1306_128_64
#define SSD1306_LCDWIDTH 128
#define SSD1306_LCDHEIGHT 64
#endif
#if defined SSD1306_128_32
#define SSD1306_LCDWIDTH 128
#define SSD1306_LCDHEIGHT 32
#endif
#if defined SSD1306_96_16
#define SSD1306_LCDWIDTH 96
#define SSD1306_LCDHEIGHT 16
#endif
#define SSD1306_SETCONTRAST 0x81
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_DISPLAYALLON 0xA5
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF
#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETCOMPINS 0xDA
#define SSD1306_SETVCOMDETECT 0xDB
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9
#define SSD1306_SETMULTIPLEX 0xA8
#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETHIGHCOLUMN 0x10
#define SSD1306_SETSTARTLINE 0x40
#define SSD1306_MEMORYMODE 0x20
#define SSD1306_MEMORY_MODE_PAGE 0x04
#define SSD1306_MEMORY_MODE_HORIZONTAL 0x00
#define SSD1306_MEMORY_MODE_VERTICAL 0x01
#define SSD1306_COLUMNADDR 0x21
#define SSD1306_PAGEADDR 0x22
#define SSD1306_COMSCANINC 0xC0
#define SSD1306_COMSCANDEC 0xC8
#define SSD1306_COM_SEQ_LR_REMAP_OFF 0x02
#define SSD1306_COM_SEQ_LR_REMAP_ON 0x12
#define SSD1306_COM_ALT_LR_REMAP_OFF 0x0A
#define SSD1306_COM_ALT_LR_REMAP_ON 0x1A
#define SSD1306_SEGREMAP 0xA0
#define SSD1306_CHARGEPUMP 0x8D
#define SSD1306_ENABLE_CHAGE_PUMP 0x14
#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2
// Scrolling #defines
#define SSD1306_ACTIVATE_SCROLL 0x2F
#define SSD1306_DEACTIVATE_SCROLL 0x2E
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
void ssd1306_startscrolldiagright(i2c_t *i2c_dev, uint16_t start, uint16_t stop);
void ssd1306_startscrolldiagleft(i2c_t *i2c_dev, uint16_t start, uint16_t stop);
void ssd1306_stopscroll(i2c_t *i2c_dev);
void ssd1306_i2c_send_command(i2c_t *i2c_dev,uint8_t c);
void ssd1306_i2c_set_display_off(i2c_t *i2c_dev);
void ssd1306_i2c_set_display_on(i2c_t *i2c_dev);
void ssd1306_i2c_set_display_clkDiv_oscFreq(i2c_t *i2c_dev, uint8_t clockDivider, uint8_t oscillatorFreq);
void ssd1306_i2c_set_multiplex_ratio(i2c_t *i2c_dev, uint8_t ratio);
void ssd1306_i2c_set_display_offset(i2c_t *i2c_dev, uint8_t offset);
void ssd1306_i2c_set_display_start_line(i2c_t *i2c_dev, uint8_t start);
void ssd1306_i2c_set_chage_pump(i2c_t *i2c_dev, uint8_t voltageSource);
void ssd1306_i2c_set_memory_addressing_mode(i2c_t *i2c_dev, uint8_t mode);
void ssd1306_i2c_set_segment_remap(i2c_t *i2c_dev, uint8_t enable);
void ssd1306_i2c_set_com_scan_direction(i2c_t *i2c_dev, uint8_t incremental);
void ssd1306_i2c_set_com_pins(i2c_t *i2c_dev, uint8_t alignment);
void ssd1306_i2c_set_contrast(i2c_t *i2c_dev, uint8_t contrast);
void ssd1306_i2c_set_dimm(i2c_t *i2c_dev, uint8_t dimm);
void ssd1306_i2c_set_prechage_period(i2c_t *i2c_dev, uint8_t period);
void ssd1306_i2c_set_com_deselect_level(i2c_t *i2c_dev, uint8_t voltageLevel);
void ssd1306_i2c_set_display_entire_on(i2c_t *i2c_dev, uint8_t resumeOrForce);
void ssd1306_i2c_set_display_invert_pixel(i2c_t *i2c_dev, uint8_t inverted);
void ssd1306_i2c_set_scroll(i2c_t *i2c_dev, uint8_t onOff);
#endif /* _SSD1306_I2C_H_ */

26
env/$ vendored

@ -1,26 +0,0 @@
#include "bsl_nucleo_f042k6.hpp"
Nucleo_f042k6::Nucleo_f042k6(){}
Nucleo_f042k6::~Nucleo_f042k6(){}
void Nucleo_f042k6::init()
{
ledPin.init();
ledPin.setMode(Pin::mode::output);
ledPin.setSpeed(Pin::speed::fast);
pin_a0.init();
pin_a0.setMode(Pin::mode::input);
pin_a0.setSpeed(Pin::speed::slow);
pin_a0.setPullUpDonw(Pin::pullUpDown::pullDown);
}
void Nucleo_f042k6::running()
{
ledPin.write(true);
delay.ms(200);
ledPin.write(false);
delay.ms(200);
}

117
env/CMakeLists.txt vendored

@ -1,117 +0,0 @@
cmake_minimum_required(VERSION 3.5)
include(config/cmakeProjectConfig.cmake)
set(CSL_DIR ${CMAKE_SOURCE_DIR}/csl/${CSL_USED})
set(CSL_SOURCES ${CMAKE_SOURCE_DIR}/csl/${CSL_USED}/Src)
if(EXISTS ${CSL_DIR}) # Cheking if the directory exists
message("${BoldGreen}Compiling for ${CSL_USED} ${ColourReset}")
set(COMPILER_DEFS config/compiler.cmake)
set(PROJECT_DEFS ${CSL_DIR}/config.cmake)
else()
message( FATAL_ERROR "${BoldRed}Please Select a valid CSL, CMake will exit.${ColourReset}" )
endif()
include(${COMPILER_DEFS})
project(${CSL_USED} ASM C CXX) #do this intead sf declaring languages in the beginning it will prevent loop errors.
set(CMAKE_VERBOSE_MAKEFILE off) #Shoul make print everythign ??
set(EXECUTABLE ${PROJECT_NAME}) #Create the executable
####################################################################################################
#CONFIG FILE
####################################################################################################
set(UTILS_DIR ${CMAKE_SOURCE_DIR}/utils/assert)
set(DRIVERS_DIR ${CMAKE_SOURCE_DIR}/drivers)
set(PERIFERALS_DIR ${CMAKE_SOURCE_DIR}/periferals)
set(OUTPUT_DOXYGEN TRUE)
####################################################################################################
#SUBDIRECTORIES Will add the given folders to the porject an check for CmakeLists.txt
####################################################################################################
include(${PROJECT_DEFS})
add_subdirectory(utils)
add_subdirectory(csl)
add_subdirectory(drivers)
add_subdirectory(periferals)
message("${BoldBlue}Project Info ${ColourReset}")
message("${Blue} |--> Exec Name \t: ${EXECUTABLE} ${ColourReset}")
message("${Blue} |--> Compiler Def\t: ${COMPILER_DEFS} ${ColourReset}")
message("${Blue} |--> Project Def\t: ${PROJECT_DEFS} ${ColourReset}")
message("${Blue} |--> Interfaces Dir\t: ${INTERFACES_DIR} ${ColourReset}")
message("${Blue} |--> Libs used\t\t: ${EXTRA_LIBS} ${ColourReset}")
####################################################################################################
#EXECUTABLE
####################################################################################################
add_executable(${EXECUTABLE} ../main.c)
target_compile_options(${EXECUTABLE} PRIVATE ${MAIN_FLAGS})
target_compile_definitions(${EXECUTABLE} PRIVATE ${MAIN_DEFS})
target_include_directories(${EXECUTABLE} PUBLIC ${MAIN_INCLUDES})
####################################################################################################
#LINKING EXECUTEABLE
####################################################################################################
if(IS_NO_SYS)
message("${Cyan}Using specifier Linker script ${ColourReset}")
message("${Cyan} |--> ${LINKER} ${ColourReset}")
target_link_libraries(${EXECUTABLE} ${EXTRA_LIBS})
target_link_options(${EXECUTABLE} PRIVATE ${LINKER_FLAGS})
else ()
message("${Cyan}Using systems linker ${ColourReset}")
target_link_libraries(${EXECUTABLE} ${EXTRA_LIBS})
endif()
####################################################################################################
#CUSTOM COMMANDS
####################################################################################################
if(NEED_OBJCOPY)
add_custom_command(TARGET ${EXECUTABLE}
POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE} ${PROJECT_NAME}.hex
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE} ${PROJECT_NAME}.bin)
endif()
add_custom_command(TARGET ${EXECUTABLE}
POST_BUILD
COMMAND ${CMAKE_SIZE} ${EXECUTABLE})
####################################################################################################
#DOXYGEN
####################################################################################################
if(OUTPUT_DOXYGEN)
find_package(Doxygen)
if (DOXYGEN_FOUND)
# set input and output files
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/config/doxyfile.in)
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/doxyfile)
# request to configure the file
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
message("Doxygen build started")
# note the option ALL which allows to build the docs together with the application
add_custom_target( doc_doxygen ALL
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM )
else (DOXYGEN_FOUND)
message("Doxygen need to be installed to generate the doxygen documentation")
endif (DOXYGEN_FOUND)
endif(OUTPUT_DOXYGEN)
####################################################################################################
#CUSTOM Comments from dev.
####################################################################################################
# Link For header dependency : https://stackoverflow.com/questions/11216408/cmake-dependencies-headers-between-apps-libraries-in-same-project
# This is one possible trick to handle the assenbly compiling.
# We can't use arm-non-eabi-as because it can onaly hande macros.
# So this bizzare Variable makes shure that whne the asembly compiling is called the -x assembler-with-cpp flag is passed
# target_compile_options(${EXECUTABLE} PRIVATE
# $<$<COMPILE_LANGUAGE:ASM>:-x assembler-with-cpp ${ASM_FLAGS}>)

@ -0,0 +1,150 @@
####################################################################################################
# DIRECTORY CHECKS
####################################################################################################
function(checkDirectory _directory)
if(EXISTS ${_directory})
else()
errorDirNotFound("${_directory}")
endif()
endfunction()
####################################################################################################
# HEADER MANAGEMENT
####################################################################################################
# This function goes an searches for directories containing header files and return the corresponding directory.
function(createHeaderDirList _directory _list _headersList)
set(_newheaderDirList)
foreach(DIR IN LISTS _list)
checkDirectory("${_directory}/${DIR}")
list(APPEND _newheaderDirList ${_directory}/${DIR})
message("${BoldMagenta} |-> Added : ${_directory}/${DIR}")
endforeach()
message("${ColourReset}")
set(${_headersList} ${_newheaderDirList} PARENT_SCOPE)
endfunction()
# This function searches for the given header file name (_alias) if it has benn included
# If it finds it it retursn the directory where the header is Located
# If it doesn't find a header it generates a fatal error
function(checkIfHeaderFileIncluded _alias _retDir)
set(_headerFound FALSE)
set(_headerDirFound)
foreach(_headerDir IN LISTS COMMON_HEADERS)
if(EXISTS ${_headerDir}/${alias}.h)
set(_headerFound TRUE)
set(_headerDirFound ${_headerDir})
endif()
endforeach()
if(_headerFound)
set(${_retDir} ${_headerDirFound}/${alias}.h PARENT_SCOPE)
else()
errorHFileNotFound(${_headerDirFound} ${_alias})
endif()
endfunction()
# This function searches for the given header file name (_alias) if it has benn included
# If it finds it it retursn the directory where the header is Located
# If it doesn't find a header it returns a Non Found Message
function(searchHeaderFile _alias _retDir)
set(_headerFound FALSE)
set(_headerDirFound)
foreach(_headerDir IN LISTS COMMON_HEADERS)
if(EXISTS ${_headerDir}/${_alias}.h)
set(_headerFound TRUE)
set(_headerDirFound ${_headerDir})
endif()
endforeach()
if(_headerFound)
set(${_retDir} ${_headerDirFound}/${_alias}.h PARENT_SCOPE)
else()
set(${_retDir} "No corresponding header << ${_alias}.h >> found " PARENT_SCOPE)
endif()
endfunction()
####################################################################################################
# SUBMODULE MANAGEMENT
####################################################################################################
function(makeSubmodules _directory _aliasList _submoduleList)
set(_newSubmoduleList)
set(_headerLoc)
#For each alias of element present on the list that has been given as argument
foreach(alias IN LISTS _aliasList)
checkDirectory("${_directory}/${alias}") # Does the directory exists (If not fatal error)
#Does the given element has an implmenetation for a CSL
if(EXISTS ${CSL_SOURCES_DIR}/imp_${alias}.${PL}) #If yes
message("${BoldCyan} |-> Target Found : ${alias} ${BoldYellow} ")
checkIfHeaderFileIncluded("${alias}" "_headerLoc") #Every Implementation has to have a header (if not Fatal Error)
#Does the given element has an predefined standart usage library
if(EXISTS ${_directory}/${alias}/${alias}.${PL}) # If yes then add this to the compiling list
message(" |-> Def Header : ${_headerLoc}")
message(" |-> Lib Source : ${_directory}/${alias}/${alias}.${PL} ")
message(" |-> Imp source : ${CSL_SOURCES_DIR}/imp_${alias}.${PL}")
add_library(${alias}_submodule ${_directory}/${alias}/${alias}.${PL} ${CSL_SOURCES_DIR}/imp_${alias}.${PL})
else() # If No than just compile the implmentation source
message(" |-> Def Header : ${_headerLoc}")
message(" |-> Imp source : ${CSL_SOURCES_DIR}/imp_${alias}.${PL}")
add_library(${alias}_submodule ${CSL_SOURCES_DIR}/imp_${alias}.${PL})
endif()
message(" |-> Name : sub::${alias}")
target_compile_options(${alias}_submodule PRIVATE ${MAIN_FLAGS})
target_compile_definitions(${alias}_submodule PRIVATE ${MAIN_DEFS})
target_include_directories(${alias}_submodule PUBLIC ${COMMON_HEADERS})
add_library(sub::${alias} ALIAS ${alias}_submodule)
#Append the internal submodule list with the newly compiled element
list(APPEND _newSubmoduleList sub::${alias})
else() # Else, when the element has no implmentation for a CSL
#If the element has an source file
if(EXISTS ${_directory}/${alias}/${alias}.${PL})
searchHeaderFile("${alias}" "_headerLoc") #Searches if there is an Header (if not it will not generate any error)
message("${BoldCyan} |-> Target Found : ${alias} ${BoldYellow} ")
message(" |-> Header : ${_headerLoc}")
message(" |-> Source : ${_directory}/${alias}/${alias}.${PL}")
message(" |-> Name : sub::${alias}")
add_library(${alias}_submodule ${_directory}/${alias}/${alias}.${PL})
target_compile_options(${alias}_submodule PRIVATE ${MAIN_FLAGS})
target_compile_definitions(${alias}_submodule PRIVATE ${MAIN_DEFS})
target_include_directories(${alias}_submodule PUBLIC ${COMMON_HEADERS})
add_library(sub::${alias} ALIAS ${alias}_submodule)
#Append the internal submodule list with the newly compiled element
list(APPEND _newSubmoduleList sub::${alias})
else() # When the element has no source file and is only a header.
message("${BoldMagenta} |-> No Source file for target : ${alias}")
message(" |-> Only headers will be added")
endif()
endif()
endforeach()
message("${ColourReset}")
#New submodule list with the names of the compiled elements
set(${_submoduleList} ${_newSubmoduleList} PARENT_SCOPE)
endfunction()
####################################################################################################
# PRINT FUNCTIONS
####################################################################################################
function(printList _txt _list)
foreach(X IN LISTS _list)
message("${_txt}${X}")
endforeach()
endfunction()

@ -0,0 +1,47 @@
function(createHeaderDirListProject _list _headersList)
foreach(DIR IN LISTS _list)
checkDirectory("${PROJECT_DIR}/${DIR}")
list(APPEND _newheaderDirList ${PROJECT_DIR}/${DIR})
message("${BoldMagenta} |-> Added : ${PROJECT_DIR}/${DIR}")
endforeach()
message("${ColourReset}")
set(${_headersList} ${_newheaderDirList} PARENT_SCOPE)
endfunction()
####################################################################################################
# SUBMODULE MANAGEMENT
####################################################################################################
function(makeSubmodulesProject _directoryList _aliasList _submoduleList)
set(_newSubmoduleList)
set(_subName)
set(_headerLoc)
foreach(_dir IN LISTS _directoryList)
checkDirectory("${PROJECT_DIR}/${_dir}") # Does the directory exists (If not fatal error)
#For each alias of element present on the list that have been given as argument
foreach(_name IN LISTS _aliasList)
if(EXISTS ${PROJECT_DIR}/${_dir}/${_name})
string(REPLACE ".c" "" _subName ${_name})
searchHeaderFile("${_subName}" "_headerLoc") #Searches if there is an Header (if not it will not generate any error)
message("${BoldGreen} |-> Directory Found : ${PROJECT_DIR}/${_dir}")
message("${BoldCyan} |-> Target Found : ${_subName} ${BoldYellow} ")
message(" |-> Header : ${_headerLoc}")
message(" |-> Source : ${PROJECT_DIR}/${_dir}/${_name}")
message(" |-> Name : sub::${_subName}")
add_library(${_subName}_submodule ${PROJECT_DIR}/${_dir}/${_subName})
target_compile_options(${_subName}_submodule PRIVATE ${MAIN_FLAGS})
target_compile_definitions(${_subName}_submodule PRIVATE ${MAIN_DEFS})
target_include_directories(${_subName}_submodule PUBLIC ${COMMON_HEADERS})
add_library(sub::${_subName} ALIAS ${_subName}_submodule)
#Append the internal submodule list with the newly compiled element
list(APPEND _newSubmoduleList sub::${_subName})
endif()
endforeach()
endforeach()
message("${ColourReset}")
#New submodule list with the names of the compiled elements
set(${_submoduleList} ${_newSubmoduleList} PARENT_SCOPE)
endfunction()

@ -1,4 +1,6 @@
####################################################################################################
# CMAKE Colors
####################################################################################################
if(NOT WIN32)
string(ASCII 27 Esc)
set(ColourReset "${Esc}[m")

@ -0,0 +1,29 @@
####################################################################################################
# DOXYGEN
####################################################################################################
function(generateDoxygen)
if(OUTPUT_DOXYGEN)
find_package(Doxygen)
if (DOXYGEN_FOUND)
set(DOXYGEN_IN ${CMAKE_CORE_DIR}/doxyfile.in)
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/doxyfile)
message("${Green}")
message("+-------------------------------+")
message("Generating Doxygen output")
message("+-------------------------------+")
message("${ColourReset}")
# request to configure the file
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
# note the option ALL which allows to build the docs together with the application
add_custom_target( doc_doxygen ALL
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
WORKING_DIRECTORY ${DOXYGEN_OUTPUT_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM )
else (DOXYGEN_FOUND)
message("Doxygen need to be installed to generate the doxygen documentation")
endif (DOXYGEN_FOUND)
endif(OUTPUT_DOXYGEN)
endfunction()

@ -0,0 +1,67 @@
function(errorDetected)
message("${Red}\n")
message("#########################################")
message("#\t@@@@ @@@ @@@ @@ @@@ \t#")
message("#\t@ @ @ @ @ @ @ @ @ \t#")
message("#\t@@@ @@@ @@@ @ @ @@@ \t#")
message("#\t@ @ @ @ @ @ @ @ @ \t#")
message("#\t@@@@ @ @ @ @ @@ @ @ \t#")
message("#########################################")
message("#\tAN ERROR HAS OCCURED\t\t#")
message("#########################################")
endfunction()
function(errorOut)
message("#########################################\n\n")
endfunction()
function(errorDirNotFound _searchedDir)
errorDetected()
message(" |-->GIVEN DIRECTORY NOT FOUND")
message(" |-> Given dir : ${DIR}")
message("!!! Possible Reasons !!!")
message(" |--> Did you give corect path in ${PROJECT_CONFIG_FILE} ??")
message(" |-> The declaration for HEADERS should look like :")
message(" |-> list(APPEND PROJECT_HEADERS_DIR \$\{PROJECT_DIR\}/path_to_header_directory")
message(" |-> \$\{PROJECT_DIR\} = ${PROJECT_DIR}")
message(" |-> The declaration for SOURCES should look like :")
message(" |-> list(APPEND PROJECT_SOURCES_DIR \$\{PROJECT_DIR\}/path_to_source_directory")
message(" |-> \$\{PROJECT_DIR\} = ${PROJECT_DIR}")
message("If A Directory has source and header files, it should be declared 2 times accordingly")
message(" |--> Once as HEADER location")
message(" |--> Once as SOURCES location")
message("\nFor more information please refer to : ${CMAKE_SOURCE_DIR}/README.md\n")
errorOut()
message(FATAL_ERROR "Directory ${DIR} : NOT FOUND")
endfunction()
function(errorHFileNotFound _directory _alias)
errorDetected()
message("The header file <<${_alias}.h>> was not found")
message(" |--> Given directory is : ${_directory}/${_alias}")
message(" |--> Given Header file path : ${_directory}/${_alias}/${_alias}.h")
message("!!! Possible Reasons !!!")
message(" |--> Did you name the module correctly in ${_directory}/CMakeLists.txt ??")
message(" |-> The module name should be : ")
message(" |-> The same as the the folder name")
message(" |-> The same as the the source name")
message(" |-> The same as the the header name")
message("\nFor more information please refer to : ${_directory}/README.md\n")
errorOut()
message(FATAL_ERROR "\n NO Header file : <<${_alias}.h>> was found ### COMPILATION ABORTED ###\n")
endfunction()
function(errorHDirNotFound _dir _alias)
errorDetected()
message("The file <<${_alias}>> was not found")
message(" |--> Given directory is : ${_directory}/${_alias}")
message("!!! Possible Reasons !!!")
message(" |--> Did you name the module correctly in ${_directory}/CMakeLists.txt ??")
message(" |-> The module name should be : ")
message(" |-> The same as the the folder name")
message(" |-> The same as the the source name")
message(" |-> The same as the the header name")
message("\nFor more information please refer to : ${_directory}/README.md\n")
errorOut()
message(FATAL_ERROR "\nNO Directory : <<${_directory}/${_alias}>> was found ### COMPILATION ABORTED ###\n")
endfunction()

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

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

@ -1,304 +0,0 @@
/**
**************************************************************************************************
* @file hardwareDescription.h
* @author Kerem Yollu & Edwin Koch
* @date 19.12.2021
* @version 1.0
**************************************************************************************************
* @brief This file contains all hardware specific definitions for STM32F042K6
*
* **Detailed Description :**
* This Header file contains all the registers and their bit manipulation options.
* All the extra Tables created here are to somplifly the main codes readability
*
* @todo
* - 19.12.2021 : implement until it runs :)
**************************************************************************************************
*/
#ifndef _hardwareDescription_H_
#define _hardwareDescription_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f042x6.h"
#include <stdint.h>
#define PACKAGE_LQFP32 1
#define MAX_USART_CHANNEL_COUNT 2
#define MAX_I2C_CHANNEL_COUNT 1
#define MAX_SPI_CHANNEL_COUNT 2
#define MAX_I2S_CHANNEL_COUNT 2
#define MAX_CAN_CHANNEL_COUNT 1
#define MAX_TIMER_CHANNEL_COUNT 6
#define MAX_N_PORTS_COUNT 3
#define MAX_PORT_PINS_COUNT 16
#define MAX_N_PIN_ALT_FUNC 8
#define MAX_PORT_A_PIN_NO 15
#define MAX_PORT_B_PIN_NO 15
#define MAX_PORT_F_PIN_NO 1
/*! Pin number typedef enum. It contains all the available pins */
typedef enum
{
// NAME = BASE ADDR | PORT | PIN NO
pinA0 = 0x00 | 0, /*!< Port: A Pin: 0 -> Port A Mask | Pin Mask */
pinA1 = 0x00 | 1, /*!< Port: A Pin: 1 -> Port A Mask | Pin Mask */
pinA2 = 0x00 | 2, /*!< Port: A Pin: 2 -> Port A Mask | Pin Mask */
pinA3 = 0x00 | 3, /*!< Port: A Pin: 3 -> Port A Mask | Pin Mask */
pinA4 = 0x00 | 4, /*!< Port: A Pin: 4 -> Port A Mask | Pin Mask */
pinA5 = 0x00 | 5, /*!< Port: A Pin: 5 -> Port A Mask | Pin Mask */
pinA6 = 0x00 | 6, /*!< Port: A Pin: 6 -> Port A Mask | Pin Mask */
pinA7 = 0x00 | 7, /*!< Port: A Pin: 7 -> Port A Mask | Pin Mask */
pinA8 = 0x00 | 8, /*!< Port: A Pin: 8 -> Port A Mask | Pin Mask */
pinA9 = 0x00 | 9, /*!< Port: A Pin: 9 -> Port A Mask | Pin Mask */
pinA10 = 0x00 | 10, /*!< Port: A Pin: 10 -> Port A Mask | Pin Mask */
pinA11 = 0x00 | 11, /*!< Port: A Pin: 11 -> Port A Mask | Pin Mask */
pinA12 = 0x00 | 12, /*!< Port: A Pin: 12 -> Port A Mask | Pin Mask */
pinA13 = 0x00 | 13, /*!< Port: A Pin: 13 -> Port A Mask | Pin Mask */
pinA14 = 0x00 | 14, /*!< Port: A Pin: 14 -> Port A Mask | Pin Mask */
pinA15 = 0x00 | 15, /*!< Port: A Pin: 15 -> Port A Mask | Pin Mask */
pinB0 = 0x10 | 0, /*!< Port: B Pin: 0 -> Port B Mask | Pin Mask */
pinB1 = 0x10 | 1, /*!< Port: B Pin: 1 -> Port B Mask | Pin Mask */
pinB3 = 0x10 | 3, /*!< Port: B Pin: 3 -> Port B Mask | Pin Mask */
pinB4 = 0x10 | 4, /*!< Port: B Pin: 4 -> Port B Mask | Pin Mask */
pinB5 = 0x10 | 5, /*!< Port: B Pin: 5 -> Port B Mask | Pin Mask */
pinB6 = 0x10 | 6, /*!< Port: B Pin: 6 -> Port B Mask | Pin Mask */
pinB7 = 0x10 | 7, /*!< Port: B Pin: 7 -> Port B Mask | Pin Mask */
pinB8 = 0x10 | 8, /*!< Port: B Pin: 8 -> Port B Mask | Pin Mask */
pinF0 = 0x20 | 0, /*!< Port: F Pin: 0 -> Port F Mask | Pin Mask */
pinF1 = 0x20 | 1 /*!< Port: F Pin: 1 -> Port F Mask | Pin Mask */
}pinNo_t;
/*!List of all possible port base addresses. This is used for the funcionality of of pin.h*/
static const uint32_t portBase_Addr_List[MAX_N_PORTS_COUNT] = {
GPIOA_BASE, //!< Base address Port A
GPIOB_BASE, //!< Base address Port B
GPIOF_BASE //!< Base address Port F
};
/*! This is a bitmap list of all possible alternative functions for each pin.
* 1means that there is an alternative function available and 0 for none. Tis is used
* for the functionality in pin.h
* */
static const uint8_t altFunc_List[MAX_N_PORTS_COUNT][MAX_PORT_PINS_COUNT] = {
{ // PORT A
0b01110000, //PA0
0b11110000, //PA1
0b01110000, //PA2
0b01110000, //PA3
0b11111000, //PA4
0b11110000, //PA5
0b11110110, //PA6
0b11111110, //PA7
0b11111000, //PA8
0b01111100, //PA9
0b11111000, //PA10
0b11111100, //PA11
0b11111100, //PA12
0b11100000, //PA13
0b11000000, //PA14
0b11110100 //PA15
},
{ // PORT B
0b11110000, //PB0
0b11110000, //PB1
0b00010000, //PB2
0b11110000, //PB3
0b11110100, //PB4
0b11110000, //PB5
0b11110000, //PB6
0b11110000, //PB7
0b11111000, //PB8
0b11111100, //PB9
0b11110100, //PB10
0b11100000, //PB11
0b11100000, //PB12
0b10100100, //PB13
0b10100100, //PB14
0b10100000 //PB15
},
{ // PORT F
0b11000000, //PF0
0b01000000, //PF1
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000, //N.A
0b00000000 //N.A
}
};
/*!
* Enum for awailable timer DS Page: 12 (block diagaram) The order of the enums is very important
* and should not be changed as it is used ofr table indexing
* */
typedef enum {
timer_1, /*!< Advanced control 16-bit timer with PWM capability RM Page: 320 */
timer_2, /*!< General purpose 32-bit timer RM Page: 393 */
timer_3, /*!< General purpose 16-bit timer RM Page: 393 */
timer_14, /*!< General purpose 16-bit timer RM Page: 459 */
timer_16, /*!< General purpose 16-bit timer RM Page: 480 */
timer_17 /*!< General purpose 16-bit timer RM Page: 480 */
} timerNo_t;
/*!
* Enum for awailable clok sources RM Page: 95
* */
typedef enum {
CLK_HSI, /*!< High speed internal */
CLK_HSE, /*!< High speed external */
CLK_LSI, /*!< Low speed internal */
CLK_LSE /*!< Low speed External */
}clkSources_t;
/*!
* Timer base addresslist of all available timers
* */
static const uint32_t timerBase_Addr_List[MAX_TIMER_CHANNEL_COUNT] = {
TIM1_BASE, /*!< Timer 1 Base Address */
TIM2_BASE, /*!< Timer 2 Base Address */
TIM3_BASE, /*!< Timer 3 Base Address */
TIM14_BASE, /*!< Timer 14 Base Address */
TIM16_BASE, /*!< Timer 16 Base Address */
TIM17_BASE /*!< Timer 17 Base Address */
};
/*!
* RCC clock enabcke bit position for the given register
* */
static const uint8_t timerBus_En_bitPos[MAX_TIMER_CHANNEL_COUNT] = {
RCC_APB2ENR_TIM1EN_Pos,
RCC_APB1ENR_TIM2EN_Pos,
RCC_APB1ENR_TIM3EN_Pos,
RCC_APB1ENR_TIM14EN_Pos,
RCC_APB2ENR_TIM16EN_Pos,
RCC_APB2ENR_TIM17EN_Pos
};
/*!
* RCC timer Reset Bit Position list
* */
static const uint8_t timerBus_Rst_bitPos[MAX_TIMER_CHANNEL_COUNT] = {
RCC_APB2RSTR_TIM1RST_Pos,
RCC_APB1RSTR_TIM2RST_Pos,
RCC_APB1RSTR_TIM3RST_Pos,
RCC_APB1RSTR_TIM14RST_Pos,
RCC_APB2RSTR_TIM16RST_Pos,
RCC_APB2RSTR_TIM17RST_Pos
};
/*!
* RCC Bus number index list connected to the timer
* */
static const uint8_t timerBus_No[MAX_TIMER_CHANNEL_COUNT] = {
2, /*!< timer 1 is connected to bus 2 */
1, /*!< timer 2 is connected to bus 1 */
1, /*!< timer 3 is connected to bus 1 */
1, /*!< timer 14 is connected to bus 1 */
2, /*!< timer 16 is connected to bus 2 */
2 /*!< timer 17 is connected to bus 2 */
};
/*!
* Timer Prescaler resolution list TO BE DELETED IF NOT NEEDED
* */
static const uint32_t timerRes_Prescaler[MAX_TIMER_CHANNEL_COUNT] = {
0xFFFF, /*!< Timer 1 Prescaler Max Value */
0xFFFF, /*!< Timer 2 Prescaler Max Value */
0xFFFF, /*!< Timer 3 Prescaler Max Value */
0xFFFF, /*!< Timer 14 Prescaler Max Value */
0xFFFF, /*!< Timer 16 Prescaler Max Value */
0xFFFF, /*!< Timer 17 Prescaler Max Value */
};
/*!
* RCC Bus number index list connected to the SPI
* */
static const uint8_t spiBus_No[MAX_SPI_CHANNEL_COUNT] = {
2, /*!< SPI 1 is connected to bus 2 */
1 /*!< SPI 2 is connected to bus 1 */
};
/*!
* RCC SPI clock enable bit position for the given register
*
*/
static const uint8_t spiBus_En_bitPos[MAX_SPI_CHANNEL_COUNT] = {
RCC_APB2ENR_SPI1EN_Pos,
RCC_APB1ENR_SPI2EN_Pos
};
/*!
* RCC SPI Reset Bit Position list
* */
static const uint8_t spiBus_Rst_bitPos[MAX_SPI_CHANNEL_COUNT] = {
RCC_APB2RSTR_SPI1RST_Pos,
RCC_APB1RSTR_SPI2RST_Pos
};
/**
* Enumof available spi hardware channels
*/
typedef enum{
SPI_CH_1,
SPI_CH_2
} spiCH_t;
/**
* SPI base address list
*/
static const uint32_t spiBase_Addr_List[MAX_SPI_CHANNEL_COUNT] = {
SPI1_BASE,
SPI2_BASE
};
/*! Awailable I2C Channels Hadware dependent Register independent */
typedef enum{
I2C_CH_1
}i2cCh_t;
/*! I2C Channel Base adress Hadware dependent Register dependent*/
static const uint32_t i2cBase_Addr_List[MAX_I2C_CHANNEL_COUNT] = {
I2C1_BASE
};
/*! RCC Bus number index list connected to the I2C */
static const uint8_t i2cBus_No[MAX_I2C_CHANNEL_COUNT] = {
1 /*!< I2C1 is connected to bus 1 */
};
/*! RCC I2C clock enable bit position for the given register*/
static const uint8_t i2cBus_En_bitPos[MAX_I2C_CHANNEL_COUNT] = {
RCC_APB1ENR_I2C1EN_Pos
};
/*! RCC I2C reset bit position for the given register*/
static const uint8_t i2cBus_Rst_bitPos[MAX_I2C_CHANNEL_COUNT] = {
RCC_APB1RSTR_I2C1RST_Pos
};
#ifdef __cplusplus
}
#endif
#endif // _hardwareDescription_H_

@ -1,280 +0,0 @@
#include "i2c.h"
#define I2C_BASE ((I2C_TypeDef*)i2cBase_Addr_List[i2cHardware->channelNo])
uint8_t temp8 = 0;
uint16_t temp16 = 0;
void i2cEnableHardware(i2c_t *i2cHardware)
{
i2cHardwareReset(i2cHardware);
// Enables the i2c bus
RCC->APB1ENR |= (1 << i2cBus_En_bitPos[i2cHardware->channelNo]);
pinInit(pinA9);
pinInit(pinA10);
pinConfig(pinA9, alternate, openDrain, pullUp, fast);// I2C SCL
pinConfig(pinA10, alternate, openDrain, pullUp, fast);// I2C CSA
pinSetAlternate(pinA9, 4);
pinSetAlternate(pinA10, 4);
}
void i2cHardwareReset(i2c_t *i2cHardware)
{
// Resete the I2C hardware using the reset registers,
RCC->APB1RSTR |= (1 << i2cBus_Rst_bitPos[i2cHardware->channelNo]);
RCC->APB1RSTR &= ~(1 << i2cBus_Rst_bitPos[i2cHardware->channelNo]);
}
void i2cEnablePeriferal(i2c_t *i2cHardware)
{
I2C_BASE->CR1 |= I2C_CR1_PE;
}
void i2cDisablePeriferal(i2c_t *i2cHardware)
{
I2C_BASE->CR1 &= ~I2C_CR1_PE;
}
void i2cSetMode(i2c_t *i2cHardware, i2cMode_t mode)
{
//This device will set himself automatically to master mode
if(i2cHardware->mode == i2cModeMaster)
{
//Automatic end mode (master mode) disabled Enablede as default
I2C_BASE->CR2 &= ~I2C_CR2_AUTOEND;
//I2C_BASE->CR2 |= I2C_CR2_AUTOEND;
}
else if(i2cHardware->mode == i2cModeSlave)
{
// to be written.
}
}
void i2cSetAddress(i2c_t *i2cHardware, uint16_t mainAddress, uint16_t secondAddress)
{
}
void i2cSetAddressLenght(i2c_t *i2cHardware, i2cAddressSize_t size)
{
if(i2cHardware->mode == i2cModeMaster)
{
if(i2cHardware->addressSize == i2cAddressSizeTenBits)
{
I2C_BASE->CR2 |= I2C_CR2_ADD10; // 10 Bit addressing
I2C_BASE->CR2 &= ~I2C_CR2_HEAD10R; // 7 Bit header read turned on DEFAULT
}
else
{
I2C_BASE->CR2 &= ~I2C_CR2_ADD10; // 7 Bit addressing DEFAULT
I2C_BASE->CR2 |= I2C_CR2_HEAD10R; // 7 Bit header read turned off DEFAULT
}
}
else if(i2cHardware->mode == i2cModeSlave)
{
// to be written.
}
}
void i2cSetClockStretch(i2c_t *i2cHardware, i2cClockStretching_t stretching)
{
if(i2cHardware->stretching == i2cClockStretchingEnable)
{
I2C_BASE->CR1 &=~ I2C_CR1_NOSTRETCH;
}
else if(i2cHardware->stretching == i2cClockStretchingDisable)
{
I2C_BASE->CR1 |= I2C_CR1_NOSTRETCH;
}
}
void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed)
{
switch(speed)
{
case i2cSpeedStandart:
I2C_BASE->TIMINGR = 0x2000090E;
break;
case i2cSpeedFast:
break;
case i2cSpeedFastPlus:
break;
case i2cSpeedHightSpeed:
break;
case i2cSpeedUltraFast:
break;
default:
break;
}
}
void i2cConfigureFilters(i2c_t *i2cHardware)
{
//Anlalog filter is on
I2C_BASE->CR1 &= ~I2C_CR1_ANFOFF;
}
/**************************************************************************************************
I2C Hardware functions
***************************************************************************************************/
void i2cGenerateStart(i2c_t *i2cHardware)
{
I2C_BASE->CR2 &=~ I2C_CR2_STOP;
I2C_BASE->CR2 |= I2C_CR2_START;
//Wait until the start condition in generated.
while(!(I2C_BASE->ISR & (I2C_ISR_BUSY)));
i2cHardware->hardwareState = i2cHwStartGenerated;
// This device places the salve address automaticalyy in the output buffer before sending the star condition
i2cHardware->hardwareState = i2cHwOutputBufferFull;
}
void i2cGenerateStop(i2c_t *i2cHardware)
{
// Send stop command
I2C_BASE->CR2 |= I2C_CR2_STOP;
I2C_BASE->CR2 &=~ I2C_CR2_START;
i2cHardware->hardwareState = i2cHwStopGenerated;
}
void i2cIsPeriferalReady(i2c_t *i2cHardware)
{
if((I2C_BASE->ISR & (I2C_ISR_BUSY))!=I2C_ISR_BUSY)
{
i2cHardware->periferalState = i2cPerifReady;
}
}
void i2cSetTransferCounter(i2c_t *i2cHardware, uint8_t count)
{
I2C_BASE->CR2 &= ~(0xFF << I2C_CR2_NBYTES_Pos);
I2C_BASE->CR2 |= (count << I2C_CR2_NBYTES_Pos);
}
void i2cSendSlaveAddress(i2c_t *i2cHardware, uint16_t *slaveAddress)
{
// The Slave addrress is automatically place on the output buffer (must be done before the start condition)
I2C_BASE->CR2 |= (*slaveAddress & 0xff) << 1; // The bit no 0 is not taken in concideration in 7bit mode
i2cGenerateStart(i2cHardware);
// Wait until the data in the ouput buffer is put to the i2c BUS
while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
{
i2cIsOutputBufferEmpty(i2cHardware);
}
}
void i2cSendRegisterAddress(i2c_t *i2cHardware, uint8_t *registerAddress)
{
i2cSendData(i2cHardware,registerAddress);
}
void i2cInitiateWriteCommand(i2c_t *i2cHardware)
{
I2C_BASE->CR2 &= ~I2C_CR2_RD_WRN;
}
void i2cInitiateReadCommand(i2c_t *i2cHardware)
{
I2C_BASE->CR2 |= I2C_CR2_RD_WRN;
}
void i2cSendData(i2c_t *i2cHardware, uint8_t *registerAddress)
{
while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
{
i2cIsOutputBufferEmpty(i2cHardware);
}
i2cSetOutputRegister(i2cHardware,registerAddress);
while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
{
i2cIsOutputBufferEmpty(i2cHardware);
}
}
void i2cIsOutputBufferEmpty(i2c_t *i2cHardware)
{
if((i2cHardware->periferalState) == i2cPerifTransmitting)
{
if((I2C_BASE->ISR & (I2C_ISR_TXIS)) == I2C_ISR_TXIS)
{
i2cHardware->hardwareState = i2cHwOutputBufferEmpty;
}
else
{
i2cHardware->hardwareState = i2cHwOutputBufferFull;
}
}
else if((i2cHardware->periferalState) == i2cPerifRecieving)
{
if((I2C_BASE->ISR & (I2C_ISR_TXE)) == I2C_ISR_TXE)
{
i2cHardware->hardwareState = i2cHwOutputBufferEmpty;
}
else
{
i2cHardware->hardwareState = i2cHwOutputBufferFull;
}
}
}
void i2cIsInputBufferEmpty(i2c_t *i2cHardware)
{
if((I2C_BASE->ISR & (I2C_ISR_RXNE)) == I2C_ISR_RXNE)
{
i2cHardware->hardwareState = i2cHwInputBufferFull;
}
else
{
i2cHardware->hardwareState = i2cHwInputBufferEmpty;
}
}
void i2cReadInputRegister(i2c_t *i2cHardware, uint8_t *data)
{
*data = I2C_BASE->RXDR;
}
void i2cSetOutputRegister(i2c_t *i2cHardware, uint8_t *data)
{
I2C_BASE->TXDR = *data;
i2cHardware->hardwareState = i2cHwOutputBufferFull;
}
void i2cIsTransferComplete(i2c_t *i2cHardware)
{
if((I2C_BASE->ISR & (I2C_ISR_TC)) == I2C_ISR_TC)
{
i2cHardware->periferalState = i2cPerifTransferComplete;
}
else
{
i2cHardware->periferalState = i2cPerifTransferOngoign;
}
}
void i2cGenerateNack(i2c_t *i2cHardware)
{
if(i2cHardware->mode == i2cModeMaster)
{
//IN master mode this ic geretes NACK's otomatically
i2cHardware->hardwareState = i2cHwSentNack;
}
else if(i2cHardware->mode == i2cModeSlave)
{
// to be written.
}
}

@ -1,13 +0,0 @@
project(Startup)
set (AS_SOURCES startup_stm32f042x6.s)
set (AS_INCLUDES ${C_INCLUDES})
set (AS_FLAGS -x assembler-with-cpp ${C_FLAGS})
set (AS_DEFS ${C_DEFS})
add_library(${PROJECT_NAME} ${AS_SOURCES})
target_compile_options(${PROJECT_NAME} PRIVATE ${AS_FLAGS})
target_compile_definitions(${PROJECT_NAME} PRIVATE ${AS_DEFS})
#To create an alias to be used on the main CMAKE.
add_library(sub::startup ALIAS ${PROJECT_NAME})

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

@ -1,5 +0,0 @@
add_library(MAX31865 max31865.c)
target_compile_options(MAX31865 PRIVATE ${C_FLAGS})
target_compile_definitions(MAX31865 PRIVATE ${C_DEFS})
target_include_directories(MAX31865 PUBLIC . ${PERIFERALS_DIR} ${CSL_INCLUDES})
add_library(sub::max31865 ALIAS MAX31865)

@ -1,5 +0,0 @@
add_library(MAX7219 max7219.c)
target_compile_options(MAX7219 PRIVATE ${C_FLAGS})
target_compile_definitions(MAX7219 PRIVATE ${C_DEFS})
target_include_directories(MAX7219 PUBLIC . ${PERIFERALS_DIR} ${CSL_INCLUDES})
add_library(sub::max7219 ALIAS MAX7219)

@ -1,45 +0,0 @@
add_library(SPI spi.c ${CSL_SOURCES}/imp_spi.c)
target_compile_options(SPI PRIVATE ${C_FLAGS})
target_compile_definitions(SPI PRIVATE ${C_DEFS})
target_include_directories(SPI PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
add_library(sub::spi ALIAS SPI)
add_library(DELAY ${CSL_SOURCES}/imp_delay.c)
target_compile_options(DELAY PRIVATE ${C_FLAGS})
target_compile_definitions(DELAY PRIVATE ${C_DEFS})
target_include_directories(DELAY PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
add_library(sub::delay ALIAS DELAY)
add_library(PIN ${CSL_SOURCES}/imp_pin.c)
target_compile_options(PIN PRIVATE ${C_FLAGS})
target_compile_definitions(PIN PRIVATE ${C_DEFS})
target_include_directories(PIN PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
add_library(sub::pin ALIAS PIN)
add_library(USART ${CSL_SOURCES}/imp_usart.c)
target_compile_options(USART PRIVATE ${C_FLAGS})
target_compile_definitions(USART PRIVATE ${C_DEFS})
target_include_directories(USART PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
add_library(sub::usart ALIAS USART)
# TODO: this point needs to be discussed. How should it work and what should it do?
add_library(INIT ${CSL_SOURCES}/deviceSetup.c)
target_compile_options(INIT PRIVATE ${C_FLAGS})
target_compile_definitions(INIT PRIVATE ${C_DEFS})
target_include_directories(INIT PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
add_library(sub::init ALIAS INIT)
add_library(I2C i2c.c ${CSL_SOURCES}/imp_i2c.c)
target_compile_options(I2C PRIVATE ${C_FLAGS})
target_compile_definitions(I2C PRIVATE ${C_DEFS})
target_include_directories(I2C PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
add_library(sub::i2c ALIAS I2C)
add_library(TIMER ${CSL_SOURCES}/imp_timer.c)
target_compile_options(TIMER PRIVATE ${C_FLAGS})
target_compile_definitions(TIMER PRIVATE ${C_DEFS})
target_include_directories(TIMER PUBLIC ${PERIFERALS_DIR} ${CSL_INCLUDES})
add_library(sub::timer ALIAS TIMER)

183
env/periferals/i2c.c vendored

@ -1,183 +0,0 @@
#include "i2c.h"
//uint32_t i2cCR1;
//uint32_t i2cCR2;
//uint32_t i2cISR;
void i2cInit( i2c_t *i2cHardware,
i2cCh_t channelNo,
i2cMode_t mode,
uint16_t mainAddress,
uint16_t secondAddress,
i2cAddressCount_t addressCount,
i2cAddressSize_t addressSize,
i2cSpeed_t speed,
i2cOpperationMode_t opperationMode,
i2cClockStretching_t stretching,
i2cWakeUpTypes_t wakeOn)
{
i2cHardware->channelNo = channelNo;
i2cHardware->mode = mode;
i2cHardware->mainAddress = mainAddress;
i2cHardware->secondAddress = secondAddress;
i2cHardware->addressCount = addressCount;
i2cHardware->addressSize = addressSize;
i2cHardware->speed = speed;
i2cHardware->opperationMode = opperationMode;
i2cHardware->stretching = stretching;
i2cHardware->wakeOn = wakeOn;
i2cHardware->hardwareState = i2cHwIdle;
i2cHardware->periferalState = i2cPerifNotInitialized;
i2cEnableHardware(i2cHardware);
i2cDisablePeriferal(i2cHardware);
i2cConfigureFilters(i2cHardware);
i2cSetClockStretch(i2cHardware, stretching);
i2cSetSpeed(i2cHardware, speed);
i2cSetMode(i2cHardware, opperationMode);
i2cSetAddressLenght(i2cHardware, addressSize);
i2cSetAddress(i2cHardware, mainAddress, secondAddress);
i2cEnablePeriferal(i2cHardware);
i2cHardware->periferalState = i2cPerifNotInitialized;
}
void i2cDeInit(i2c_t *i2cHardware)
{
}
void i2cRead(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
{
switch(i2cHardware->mode)
{
case i2cModeMaster:
i2cMasterRecieve(i2cHardware, slaveAddress, registerAddress, data);
break;
case i2cModeSlave:
break;
case i2cModeMultyMaster:
break;
}
}
// this function still doesn't implment 10 bit oopeartion
void i2cMasterRecieve(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data)
{
switch(i2cHardware->opperationMode)
{
case i2cOpperationPolling :
i2cMasterRecievePolling(i2cHardware, slaveAddress, registerAddress, data);
break;
case i2cOpperationInt:
break;
case i2cOpperationDma:
break;
}
}
void i2cWrite(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
{
switch(i2cHardware->mode)
{
case i2cModeMaster:
i2cMasterSend(i2cHardware, slaveAddress, registerAddress, data);
break;
case i2cModeSlave:
break;
case i2cModeMultyMaster:
break;
}
}
void i2cMasterSend(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data)
{
switch(i2cHardware->opperationMode)
{
case i2cOpperationPolling :
i2cMasterSendPolling(i2cHardware, slaveAddress, registerAddress, data);
break;
case i2cOpperationInt:
break;
case i2cOpperationDma:
break;
}
}
void i2cMasterSendPolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data)
{
while(i2cHardware->periferalState != i2cPerifReady)
{
i2cIsPeriferalReady(i2cHardware);
}
i2cHardware->periferalState = i2cPerifTransmitting;
i2cInitiateWriteCommand(i2cHardware);
i2cSetTransferCounter(i2cHardware,2);
i2cSendSlaveAddress(i2cHardware, slaveAddress);
i2cSendRegisterAddress(i2cHardware,registerAddress);
i2cSendData(i2cHardware,data);
while(i2cHardware->periferalState != i2cPerifTransferComplete)
{
i2cIsTransferComplete(i2cHardware);
}
i2cGenerateStop(i2cHardware);
i2cHardware->periferalState = i2cPerifReady;
i2cHardware->hardwareState = i2cHwIdle;
}
void i2cMasterRecievePolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data)
{
while(i2cHardware->periferalState != i2cPerifReady)
{
i2cIsPeriferalReady(i2cHardware);
}
i2cHardware->periferalState = i2cPerifTransmitting;
i2cSetTransferCounter(i2cHardware,1);
i2cInitiateWriteCommand(i2cHardware);
i2cSendSlaveAddress(i2cHardware, slaveAddress);
i2cSendRegisterAddress(i2cHardware,registerAddress);
while(i2cHardware->periferalState != i2cPerifTransferComplete)
{
i2cIsTransferComplete(i2cHardware);
}
i2cInitiateReadCommand(i2cHardware);
i2cSendSlaveAddress(i2cHardware, slaveAddress);
i2cHardware->periferalState = i2cPerifRecieving;
while(i2cHardware->hardwareState != i2cHwInputBufferFull)
{
i2cIsInputBufferEmpty(i2cHardware);
}
i2cGenerateNack(i2cHardware);
i2cGenerateStop(i2cHardware);
i2cReadInputRegister(i2cHardware, data);
i2cHardware->periferalState = i2cPerifReady;
i2cHardware->hardwareState = i2cHwIdle;
}

552
env/periferals/i2c.h vendored

@ -1,552 +0,0 @@
/**
**************************************************************************************************
* @file i2c.h
* @author Kerem Yollu & Edwin Koch
* @date 18.07.2022
* @version 1.01
**************************************************************************************************
* @brief I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips :
* following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA
* This will also not have a I3C support for the forseable futrue.
*
* **Detailed Description :**
*
* I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips :
* following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA
* This will also not have a I3C support for the forseable futrue.
*
* @todo
* - 26.07.2021 : Implement the DMA
* - 26.07.2021 : Implement the Interrupt
* - 26.07.2021 : Implement the Sleep/WakeUp
* - 26.07.2021 : Implement the Slave opperation
**************************************************************************************************
*/
#ifndef _I2C_H_
#define _I2C_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "hardwareDescription.h"
#include "pin.h"
/*! Enum of possible I2C opperation modes */
typedef enum{
i2cModeMaster, /*!< Master mode : In Master mode, the I2C interface initiates
a data transfer and generates the clock signal. **DEFAULT** */
i2cModeMultyMaster, /*!< Multimaster Mode : In case if more than one master are present
in one I2C bus. In such case each device needs to be able to
cooperate knowing that another device could talking
therefore the bus is busy (Arbirtation).
For More information : https://www.i2c-bus.org/multimaster/ */
i2cModeSlave /*!< Slave mode : A slave device has to always be ready to detect and
process a start condition and to recognize its address */
}i2cMode_t;
/*! Enum of possible I2C speeds */
typedef enum{
i2cSpeedStandart, /*!< SM 100 kbits/s Standart i2c Speed **DEFAULT** */
i2cSpeedFast, /*!< FM 400 kbits/s */
i2cSpeedFastPlus, /*!< FM+ 1 Mbits/s */
i2cSpeedHightSpeed, /*!< HS 3.4 Mbits/s */
i2cSpeedUltraFast /*!< UFM 5 Mbits/s */
}i2cSpeed_t;
/*! Enum of possible I2C Adress sizes */
typedef enum{
i2cAddressSizeSevenBits, /*!< 7 Bits address size **DEFAULT** */
i2cAddressSizeTenBits /*!< 10 Bits address size */
}i2cAddressSize_t;
/*! Enum of possible I2C Address count */
typedef enum{
i2cAddressCountSingle, /*!< Only one address for communication **DEFAULT** */
i2cAddressCountDual /*!< Dual addresses for one device respondng to two addresses */
}i2cAddressCount_t;
/*! Enum for clock strechning activation. Can only be implmented as Slave
* for more information : https://www.i2c-bus.org/clock-stretching/ */
typedef enum{
i2cClockStretchingDisable, /*!< We assume that the master and slave have compatible
Clock frequencies **DEFAULT** */
i2cClockStretchingEnable /*!< In situations where an I2C slave is not able to co-operate
with the clock speed given by the master and needs to slow down.
This is done by a mechanism referred to as clock stretching. */
}i2cClockStretching_t;
/*! Enum for diffenrent wake up methodes wehnin sleep mode */
typedef enum{
i2cWakeUpDisabled, /*!< No wake up is possible this is the default mode also means that
the sleep function is not implmentes **DEFAULT** */
i2cWakeUpOnAddressMatch /*!< Wakes up on address match, this can be harware dependent */
}i2cWakeUpTypes_t;
/*! Enum operation mode of the i2c channel */
typedef enum{
i2cOpperationPolling, /*!< Polling mode Blocking, i2c communication states are constantly
checked on polling mode so it can be stoped
when interrupts occures **DEFAULT** */
i2cOpperationInt, /*!< Interrut Mode Non-blocking, i2c communications state changes
generates an interrupt and can be handeled this way */
i2cOpperationDma /*!< DMA Mode Non-blocking, I2C communication satets are managed
via Inteerupts and with Direct Memory Access */
}i2cOpperationMode_t;
/*! typedef for the i2c states*/
typedef enum
{
i2cHwIdle, /*!< Hardware is in Idle Mode **DEFAULT** */
i2cHwStartGenerated, /*!< Generated the star condition */
i2cHwOutputBufferFull, /*!< The output buffer of the I2C Periferal is Full */
i2cHwOutputBufferEmpty, /*!< The output buffer of the I2C Periferal is Empty */
i2cHwInputBufferFull, /*!< The input buffer of the I2C Periferal Is Full */
i2cHwInputBufferEmpty, /*!< The input buffer of the I2C Periferal Is Empty */
i2cHwSentRead, /*!< Sent read request */
i2cHwSentWrite, /*!< Sent write request */
i2cHwGotAck, /*!< Recieved ACK */
i2cHwGotNack, /*!< Recieved NACK */
i2cHwSentAck, /*!< Sent ACK */
i2cHwSentNack, /*!< Sent NACK */
i2cHwStopGenerated, /*!< Generated the star condition */
i2cHwError /*!< Error */
} i2cHardwareState_t;
typedef enum
{
i2cPerifNotInitialized, /*!< Default Peripheral is not yet Initialized **DEFAULT** */
i2cPerifInitialized, /*!< I2C CHannle is initilized but not neceserly ready */
i2cPerifSlaveAddressSent, /*!< The Salve Address Was Sent to the bus */
i2cPerifTransferComplete, /*!< A full communication process is complete (wire or Read) */
i2cPerifTransferOngoign, /*!< A full communication process is in progress (wire or Read) */
i2cPerifReady, /*!< Peripheral Initialized and ready for use */
i2cPerifSlaveNotFound, /*!< Desired Slave was not able to be found */
i2cPerifTransmitting, /*!< Data Transmission process is ongoing */
i2cPerifRecieving, /*!< Data Reception process is ongoing */
i2cPerifListening, /*!< Address Listen Mode is ongoing */
i2cPerifListeningAndTransmitting, /*!< Address Listen Mode and ongoing Data Transmission */
i2cPerifListeningAndRecieveing, /*!< Address Listen Mode and ongoing Data Reception */
i2cPerifAbort, /*!< Abort user request ongoing */
i2cPerifTimeout, /*!< Timeout state */
i2cPerifError /*!< Error */
} i2cPeriferalState_t;
/*! Struture a an i2c channel with all the required propereties*/
typedef struct i2c_t
{
i2cCh_t channelNo; /*!< The harware channel to be used */
i2cMode_t mode; /*!< Master, Slave or Multymaster Modes */
uint16_t mainAddress; /*!< First and Main address of the device */
uint16_t secondAddress; /*!< Second address if dual addresse mode is configured */
i2cAddressCount_t addressCount; /*!< Single or multiple */
i2cAddressSize_t addressSize; /*!< 10 or 7 bit address size */
i2cSpeed_t speed; /*!< Bus Speed */
i2cOpperationMode_t opperationMode; /*!< Blocking or non blocking polling, Int or DMA */
i2cClockStretching_t stretching; /*!< Clock Stretching enable onyl in slave mode */
i2cWakeUpTypes_t wakeOn; /*!< Define on which type of action the i2c channel should
wake up. Only if de prefiral goes to sleep */
i2cHardwareState_t hardwareState; /*!< The current sitate of the I2C Bus */
i2cPeriferalState_t periferalState; /*!< The current sitate of the I2C Bus */
}i2c_t;
/***************************************************************************************************
I2C Configuration functions
***************************************************************************************************/
/**
* @brief Initilize the I2C Hardware
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cInit( i2c_t *i2cHardware, /*!< Pointer to I2C hardware Object */
i2cCh_t channelNo, /*!< The harware channel to be used */
i2cMode_t mode, /*!< Master, Slave or Multymaster Modes */
uint16_t mainAddress, /*!< First and Main address of the device */
uint16_t secondAddress, /*!< Second address if dual addresse mode is configured */
i2cAddressCount_t addressCount, /*!< Single or multiple */
i2cAddressSize_t addressSize, /*!< 10 or 7 bit address size */
i2cSpeed_t speed, /*!< Bus Speed */
i2cOpperationMode_t opperationMode, /*!< Blocking or non blocking polling, Int or DMA */
i2cClockStretching_t stretching, /*!< Clock Stretching enable onyl in slave mode */
i2cWakeUpTypes_t wakeOn /*!< Wake up condition */
);
/**
* @brief De-Initilize the I2C Hardware
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cDeInit(i2c_t *i2cHardware);
/**
* @brief Set the i2c channle to the gievn mode
* @param Channel is the i2c hardware channel
* @param mode The mode for i2c : Master Slave or Multymaster
*/
void i2cSetMode(i2c_t *i2cHardware, i2cMode_t mode);
/**
* @brief Set the i2c channles mode as Master Slave or Multymaster
* @param i2cHardware is the i2c hardware channel
* @param addressOne The forst address for the device
* @param addressTwo The second address for the device only if dual address mode is not defined
*/
void i2cSetAddress(i2c_t *i2cHardware, uint16_t mainAddress, uint16_t secondAddress);
/**
* @brief Set the i2c Address Lenght, 7 bit or 8 bit, Master or slave doesn't make any difference
* @param i2cHardware is the i2c hardware channel
* @param size Is the Adress isze to be used 7 Bit or 10 Bit
*/
void i2cSetAddressLenght(i2c_t *i2cHardware, i2cAddressSize_t size);
/**
* @brief Stets the Communication speed
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param speed the different awailable speeds
*/
void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed);
/**
* @brief Initiates the opperation mode for the selected i2c Channel
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param opperation define if the i2c channel will opperate on pollin, Interrupt, or DMA modes
*/
void i2cSetOpperation(i2c_t *i2cHardware, i2cOpperationMode_t opperation);
/**
* @brief Ebales or disables clock stretching functionalities
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param The value to be written in the register. This will heavily depend on the hardware
*/
void i2cSetClockStretch(i2c_t *i2cHardware, i2cClockStretching_t stretching);
/**
* @brief Set the wakeup mode
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param wake the desider wakeup mode for now i have found only one mode.
*/
void i2cSetWakeup(i2c_t *i2cHardware, i2cWakeUpTypes_t wake);
/**
* @brief Configures Hardware implmente filters if there are any.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cConfigureFilters(i2c_t *i2cHardware);
/**
* @brief Set the timeout to close the i2c wait time if a communication fails.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param timeout the desider timeout duration in ticks.
*/
void i2cSetTimeout(i2c_t *i2cHardware, uint8_t timeout);
/**
* @brief Resets the i2c Periferal to it's inital state.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cPeriferalReset(i2c_t *i2cHardware);
/**
* @brief Resets the i2c Harware and register to it's factory deflauts.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cHardwareReset(i2c_t *i2cHardware);
/**
* @brief Enables I2C Hardware BUS & Clock & Pins
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cEnableHardware(i2c_t *i2cHardware);
/**
* @brief Enables I2C Periferal core.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cEnablePeriferal(i2c_t *i2cHardware);
/**
* @brief Disables I2C Periferal core.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cDisablePeriferal(i2c_t *i2cHardware);
/**************************************************************************************************
I2C Communication functions independen of opperating mode
***************************************************************************************************/
/**
* @brief Writes the given amount of data to the selected device. This function will
* automaticaly choose between i2cMasterSend(); or i2cSlaveSend();
* Depending if the I2C channel was initiated as slave or master.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data to be written
* @param dataLenght is the total quantity of 8 bit data to be written.
*/
void i2cWrite(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
/**
* @brief Reads the given amount of data to the selected device. This function will
* automaticaly choose between i2cMasterRecieve(); or i2cSlaveRecieve();
* Depending if the I2C channel was initiated as slave or master.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data which has been red
* @paran dataLenght is the total quantity of 8 bit data to be red
*/
void i2cRead(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
/**
* @brief Recieve a Single Byte as master from from the given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2cMasterRecieve(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Sends a Single Byte as master to the given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the send command will be sent
* @param registerAddress is the regiter to be written to the device
* @param data is the data to be sent
*/
void i2cMasterSend(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Recieve a Single Byte as slave from given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2cSlaveRecieve(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Recieve a Single Byte as slave from the given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2cSlaveSend(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**************************************************************************************************
I2C Hardware functions
***************************************************************************************************/
/**
* @brief Checks if the device is ready for any type of communication
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cIsPeriferalReady(i2c_t *i2cHardware);
/**
* @brief Generates a Start condition.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cGenerateStart(i2c_t *i2cHardware);
/**
* @brief Generates a Start condition.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cGenerateStop(i2c_t *i2cHardware);
/**
* @brief Generates a NACK condition.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cGenerateNack(i2c_t *i2cHardware);
/**
* @brief Generates a ACK condition.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cGenerateAck(i2c_t *i2cHardware);
/**
* @brief Initiates the communication protocl by sending the slave address on the bus and waits
* for an ACK (aknowledge)
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress The address of the slave to be communicated
*/
void i2cSendSlaveAddress(i2c_t *i2cHardware, uint16_t *slaveAddress);
/**
* @brief Sende the register adrres with which we want to communicate.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param registerAddress The register address of the slave device that we are communication with
*/
void i2cSendRegisterAddress(i2c_t *i2cHardware, uint8_t *registerAddress);
/**
* @brief Send the register that we want to read or write.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param registerAddress the register that need to be accessed
*/
void i2cSendData(i2c_t *i2cHardware, uint8_t *registerAddress);
/**
* @brief Initiates a Write command with the previously set slave address.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cInitiateWriteCommand(i2c_t *i2cHardware);
/**
* @brief Initiates a read command with the previously set slave address.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cInitiateReadCommand(i2c_t *i2cHardware);
/**
* @brief Is the output buffer empty. This allso meas that the data that was in the ouput buffer
* is sent to the i2c BUS.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cIsOutputBufferEmpty(i2c_t *i2cHardware);
/**
* @brief Is the output buffer empty. This allso meas that the data that was in the ouput buffer
* is sent to the i2c BUS.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cIsInputBufferEmpty(i2c_t *i2cHardware);
/**
* @brief reads the I2C input buffer
* is sent to the i2c BUS.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param data pointer to the data that need to be read and returned
*/
void i2cReadInputRegister(i2c_t *i2cHardware, uint8_t *data);
/**
* @brief writes to the I2C output buffer
* is sent to the i2c BUS.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param data pointer to the data that need to be read and returned
*/
void i2cSetOutputRegister(i2c_t *i2cHardware, uint8_t *data);
/**
* @brief Checks is transfer is complete
* is sent to the i2c BUS.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param data pointer to the data that need to be read and returned
*/
void i2cIsTransferComplete(i2c_t *i2cHardware);
/**
* @brief Defines the amount of transfers to be made. Address exchange and start conditon does not count
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param count amount o data to be transfered.
*/
void i2cSetTransferCounter(i2c_t *i2cHardware, uint8_t count);
/**************************************************************************************************
I2C Communication functions Polling / Blocking Mode
***************************************************************************************************/
/**
* @brief Recieve a Single Byte in polling mode as master from from the given devices register.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2cMasterRecievePolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Sends a Single Byte in polling mode as master to the given devices register.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the send command will be sent
* @param registerAddress is the regiter to be written to the device
* @param data is the data to be sent
*/
void i2cMasterSendPolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Recieve a Single Byte in polling mide as slave from the given devices register.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2cSlaveRecievePolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Recieve a Single Byte in polling mode as slave from the given devices register.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2cSlaveSendPolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**************************************************************************************************
I2C Arbitration Functions for Multymaster mode and slaves clock stretching
***************************************************************************************************/
void i2cClockSynchronise(); // I2C Standart : Clock Syncronization
void i2cAbortTransmit(); // I2c Standart : Stop Communication for multimaster mode
void i2cArbitration(); // I2C Standart : Arbitration for multimaster mode to define the right master.
void i2cSoftReset(); // I2C Standart : Software reset not supported by all hardware.
void i2cBusClear(); // I2C Standart : in case if SCL is stuck
/**************************************************************************************************
I2C Extra functions that are not esential for the main functionality
***************************************************************************************************/
/**
* @brief This function will scan every for possible addresses to discover devices on the bus.
* And write them to the Devices list given to him. This function will not discover more
* devices than what he is told.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devices list where the discevered devices will be written
* @param deviceCount Max number of devices to be discovered.
*/
void i2cDiscoverDevices(i2c_t *i2cHardware, uint16_t *devices, uint8_t deviceCount);
/**
* @brief This function will try to communicate with a device with every speed
* allowed by his hardware to find out the maximum communication sppeed possible.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
*/
i2cSpeed_t i2cTestDeviceSpeed(i2c_t *i2cHardware, uint16_t *slaveAddress);
/**
* @brief This function will read the device info register (if awailable) as follows :
* I2c Standart : 3 Bytes (24 bits) | 12 Bits : Manufacturer info | 9 Bits: Part Identification | 3 Bits DIE Rev.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to be red
*/
uint32_t i2cReadDeviceInfo(i2c_t *i2cHardware, uint16_t *slaveAddress);
/**
* @brief The selected i2c channel is put on sleep.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cSleep(i2c_t *i2cHardware);
/**
* @brief Error handling.
* @param error The error no generated.
*/
void i2cThrowError(int16_t error); // Defined by me : Private error function for error handling
#ifdef __cplusplus
}
#endif
#endif // _I2C_H_

@ -0,0 +1,28 @@
import sys
import os
import subprocess
def eraseFirmware(TARGET_DEVICE):
if sys.platform == 'linux':
print('TODO')
if sys.platform == 'win32':
subprocess.Popen("STM32_Programmer_CLI.exe -c port=SWD -fwdelete")
def downloadFirmware(TARGET_DEVICE):
print('TODO')
def flash(TARGET_DEVICE, buildDirectory):
# find out what platform the build is done (e.g. linux, win32, etc.)
if sys.platform == 'linux':
os.system('st-flash write' + TARGET_DEVICE + '.bin 0x08000000')
sys.exit()
if sys.platform == 'win32':
# https://www.youtube.com/watch?v=AcrbUOhApd0
os.chdir('C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin')
#subprocess.Popen("STM32_Programmer_CLI.exe")
subprocess.Popen("STM32_Programmer_CLI.exe")
os.chdir(buildDirectory)
sys.exit()
print('this platform is not supported by KED!')

Binary file not shown.

158
env/python/ked.py vendored

@ -0,0 +1,158 @@
'''
KED Main Script
'''
import sys
import os
import shutil
import subprocess
import flasher
####################################################################################################
# FUTURE ACTIONS
####################################################################################################
# TODO: KeY 14_02_2023 -> Automatically generate project, if empty.
# TODO: KeY 14_02_2023 -> Give the possibility to generate different example projects.
####################################################################################################
####################################################################################################
# MODIFICATIONS
####################################################################################################
# KeY 14_02_2023 : Some comments for code separation added :
# FUTURE ACTIONS, MODIFICATIONS, FUNCTIONS and MAIN EXECUTION Delimiters
#
# KeY 14_02_2023 : Modified some Print's for user guidance and apearance changes
# KeY 14_02_2023 : Gave a response to CSL_TO_USE question from Edwin
####################################################################################################
####################################################################################################
# FUNCTIONS
####################################################################################################
class bcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
def getTargetDeviceList():
os.chdir(os.path.join(os.getcwd(), 'csl'))
# get top level folder names in csl which represent all available target devices
return next(os.walk('.'))[1]
def build(TARGET_DEVICE):
# TODO: ask Kerem what he wanted to to with "CSL_TO_USE"
# KeY 14_02_2023 RESPONSE:
# CSL_TO_USE is the "folder name" given to CMAKE
# so that CMAKE gets the correct "file path" under the csl directory.
# Like so: csl/<CSL_TO_USE> | Real example: csl/stm32f042
print('building project with cmake...')
print(bcolors.OKGREEN)
os.system('cmake -S . -B '+ buildDirectory + ' -DCSL_USED=' + TARGET_DEVICE)
print(bcolors.ENDC)
print('...done!')
print('Compiling Project with Make...')
os.chdir(buildDirectory)
print(bcolors.OKGREEN)
os.system('make -j4')
print(bcolors.ENDC)
print('...done!')
'''
def flash(TARGET_DEVICE):
# find out what platform the build is done (e.g. linux, win32, etc.)
if sys.platform == 'linux':
os.system('st-flash write' + TARGET_DEVICE + '.bin 0x08000000')
if sys.platform == 'win32':
# https://www.youtube.com/watch?v=AcrbUOhApd0
os.chdir('C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin')
subprocess.Popen("STM32_Programmer_CLI.exe")
os.chdir(buildDirectory)
print('this platform is not supported by KED!')
'''
####################################################################################################
####################################################################################################
# MAIN EXECUTION
####################################################################################################
scriptDirectory = os.getcwd()
projectDirectory = os.path.join(scriptDirectory, '..')
buildDirectory = os.path.join(projectDirectory, 'ked_build')
#projectDirectory = scriptDirectory + '\\..'
#buildDirectory = projectDirectory + '\\ked_build'
os.chdir(scriptDirectory)
# exit if no argument was passed
argvLen = len(sys.argv)
if argvLen < 2:
print('Target Device missing as argument!')
sys.exit()
# obtain list of all available targets in KED
targetDevList = getTargetDeviceList()
# user requests help
if sys.argv[1] in ('-h', '-help'):
print('HELP -> TODO!')
sys.exit()
# user request to remove build folder
if sys.argv[1] in ('-rm', '-rmb'):
if os.path.exists(buildDirectory):
shutil.rmtree(buildDirectory)
sys.exit()
# user requests listing of all available target devices
# KeY 14_02_2023 : Could not help my self wiht some pimping
if sys.argv[1] in ('-ls', '-lt', '-lst', '-lsd'):
print('----------------------------')
print('| Available Traget Devices |')
print('----------------------------')
for targetDev in targetDevList:
print(" - " + targetDev)
sys.exit()
# user requests to clean project by erasing build
if sys.argv[1] in ('-clean', '-c', '-db'):
if os.path.exists(buildDirectory):
shutil.rmtree(buildDirectory)
os.mkdir(buildDirectory)
print('build cleaned!')
sys.exit()
if sys.argv[1] in ('-dox', '-doxygen', '-gd'):
print('TODO: Implement doxygen generation')
sys.exit()
if sys.argv[1] in ('-opendox', '-od'):
print('TODO: Implement open doxygen in browser')
sys.exit()
# check if requested target device is supported by KED
# KeY : 14_02_2023 : Jsut changed the text a little bit and gave some guidance to the user.
if sys.argv[1] not in targetDevList:
print('debug: Invalid Target Device')
print(' |-> To list the availabe target devices pass -ls as argument')
print(' |-> python ked.py -ls')
sys.exit()
print('building for target device ['+ bcolors.OKGREEN + sys.argv[1] + bcolors.ENDC + ']...')
#create build directory if missing
if not os.path.exists(buildDirectory):
os.mkdir(buildDirectory)
CSL_TO_USE = sys.argv[1]
build(CSL_TO_USE)
#flasher.flash(CSL_TO_USE,buildDirectory)

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

Loading…
Cancel
Save