Compare commits

...

107 Commits
spi ... master

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
kerem 6da5c4c144 Cleaned the Main main.c ti have a clean start with uart and blinking LED
3 years ago
kerem 91513ad6b3 added interrupt main.c in examples file
3 years ago
kerem f84f682edf i2c.c doxgen comments deleted
3 years ago
kerem 741bca811f Fixed Doxygen and cahged rules to be recursive
3 years ago
kerem edf78539a2 Implementation of the new structure
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_

@ -1,39 +1,25 @@
/**
**************************************************************************************************
* @file hardwareDescription.h
* @author Kerem Yollu & Edwin Koch
* @date 19.12.2021
* @file hwd_pin.h
* @author Kerem Yollu & Edwin Koch
* @date 26.02.2023
* @version 1.0
**************************************************************************************************
* @brief This file contains all hardware specific definitions for STM32F042K6
* @brief
*
* **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_
#ifndef _HWD_PIN_H_
#define _HWD_PIN_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
#include "hardwareDescription.h"
#define MAX_N_PORTS_COUNT 3
#define MAX_PORT_PINS_COUNT 16
@ -145,105 +131,8 @@ static const uint8_t altFunc_List[MAX_N_PORTS_COUNT][MAX_PORT_PINS_COUNT] = {
}
};
/*!
* 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 */
};
typedef enum{
SPI_CH_1,
SPI_CH_2
} spiCH_t;
static const uint32_t spiBase_Addr_List[MAX_SPI_CHANNEL_COUNT] = {
SPI1_BASE,
SPI2_BASE
};
#ifdef __cplusplus
}
#endif
#endif // _hardwareDescription_H_
#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,13 +1,3 @@
####################################################################################################
# bsl_nucleo_f042k6.cmake
####################################################################################################
set(CPU_MCU "-mcpu=cortex-m0")
#set(IDIR_BIN "${CMAKE_SOURCE_DIR}/bsl/nucleo_f042k6/bin")
#set(IDIR_LIB "${CMAKE_SOURCE_DIR}/bsl/nucleo_f042k6/lib")
#set(IDIR_INC "${CMAKE_SOURCE_DIR}/bsl/nucleo_f042k6/inc")
####################################################################################################
#PROJECT & LIBRARIES : defined by user and important that it comes after the VARIABLES otherwise the Set varibale will not be used.
####################################################################################################
@ -16,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
@ -38,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
@ -53,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
@ -64,17 +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::translator)
list(APPEND EXTRA_LIBS sub::delay)
list(APPEND EXTRA_LIBS sub::pin)
list(APPEND EXTRA_LIBS sub::usart)
list(APPEND EXTRA_LIBS sub::timer)
list(APPEND EXTRA_LIBS sub::init)
list(APPEND EXTRA_LIBS sub::spi)
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);
}

@ -0,0 +1,161 @@
#include "spi.h"
#include "hardwareDescription.h"
#include "hwd_spi.h"
#include "interrupt.h"
#define SPI_BASE ((SPI_TypeDef *)spiBase_Addr_List[spi_hw_ch])
void spiReset(spiCH_t spi_hw_ch)
{
if(spiBus_No[spi_hw_ch] == 1) {
RCC->APB1RSTR |= (1 << spiBus_Rst_bitPos[spi_hw_ch]);
RCC->APB1RSTR &= ~(1 << spiBus_Rst_bitPos[spi_hw_ch]);
return;
}
RCC->APB2RSTR |= (1 << spiBus_Rst_bitPos[spi_hw_ch]);
RCC->APB2RSTR &= ~(1 << spiBus_Rst_bitPos[spi_hw_ch]);
}
void spiEnableBus(spiCH_t spi_hw_ch)
{
if(spiBus_No[spi_hw_ch] == 1) {
RCC->APB1ENR |= (1 << spiBus_En_bitPos[spi_hw_ch]);
return;
}
RCC->APB2ENR |= (1 << spiBus_En_bitPos[spi_hw_ch]);
}
void spiEnable(spiCH_t spi_hw_ch)
{
SPI_BASE->CR1 |= SPI_CR1_SPE;
}
void spiDissable(spiCH_t spi_hw_ch)
{
// TODO: implement p.768 procedure for dissabling
//while(SPI_BASE->SR
SPI_BASE->CR1 &= ~SPI_CR1_SPE;
}
void spiSetMode(spiCH_t spi_hw_ch, spi_mode_t mode)
{
SPI_BASE->CR1 &= ~(mode << SPI_CR1_MSTR_Pos);
SPI_BASE->CR1 |= mode << SPI_CR1_MSTR_Pos;
// TODO: find out if this is the correct place to set the SSOE bit
SPI_BASE->CR2 &= ~SPI_CR2_SSOE;
if(mode == SPI_MASTER) {
SPI_BASE->CR2 |= SPI_CR2_SSOE;
}
}
void spiSetPolarity(spiCH_t spi_hw_ch, spi_clkPol_t clkPol)
{
// reset
SPI_BASE->CR1 &= ~SPI_CR1_CPOL;
// set
SPI_BASE->CR1 |= clkPol << SPI_CR1_CPOL_Pos;
}
void spiSetPhase(spiCH_t spi_hw_ch, spi_phase_t phase)
{
// reset
SPI_BASE->CR1 &= ~(phase << SPI_CR1_CPHA_Pos);
// set
SPI_BASE->CR1 |= phase << SPI_CR1_CPHA_Pos;
}
void spiSetBitFrameLength(spiCH_t spi_hw_ch, spi_framel_t framel)
{
SPI_BASE->CR2 &= ~(SPI_CR2_FRXTH | SPI_CR2_DS);
// using p.974 as example
if(framel == SPI_FRAME_LENGTH_8BIT) {
// set FIFO reception threshold to 8 bit
SPI_BASE->CR2 |= SPI_CR2_FRXTH;
// set transfer lwnght to 8 bit
SPI_BASE->CR2 |= SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2;
return;
}
SPI_BASE->CR2 |= SPI_CR2_DS;
}
void spiSetFrameFormat(spiCH_t spi_hw_ch, spi_framef_t framef)
{
// reset
SPI_BASE->CR1 &= ~SPI_CR1_LSBFIRST;
// set
SPI_BASE->CR1 |= framef << SPI_CR1_LSBFIRST_Pos;
}
spi_framef_t spiGetFrameFormat(spiCH_t spi_hw_ch)
{
return (spi_framef_t)(SPI_BASE->CR1 & SPI_CR1_LSBFIRST) >> SPI_CR1_LSBFIRST_Pos;
}
void spiSetClockPrescaler(spiCH_t spi_hw_ch, uint32_t clkDiv)
{
// reset
SPI_BASE->CR1 &= ~SPI_CR1_BR;
// set
SPI_BASE->CR1 |= (clkDiv << SPI_CR1_BR_Pos) & SPI_CR1_BR;
}
void spiSetComMode(spiCH_t spi_hw_ch, spi_comMode_t comMode)
{
// reset
SPI_BASE->CR1 &= ~SPI_CR1_RXONLY;
// set
SPI_BASE->CR1 |= comMode << SPI_CR1_RXONLY_Pos;
}
void spiSetSoftwareSlaveManagement(spiCH_t spi_hw_ch, uint8_t logic)
{
SPI_BASE->CR1 &= ~SPI_CR1_SSM;
if(logic){
SPI_BASE->CR1 |= SPI_CR1_SSM;
}
}
void spiSetInternalSlaveSelect(spiCH_t spi_hw_ch, uint8_t logic)
{
SPI_BASE->CR1 &= ~SPI_CR1_SSI;
if(logic) {
SPI_BASE->CR1 |= SPI_CR1_SSI;
}
}
uint8_t spiTrx8BitPolling(spiCH_t spi_hw_ch, uint8_t tx_data)
{
// wait for BSY bit to Reset -> This will indicate that SPI is not busy in communication
while (SPI_BASE->SR & SPI_SR_BSY);
// from example code p.975 f
// this masking must be done. otherwise 16bits frame will be used
*(uint8_t*)&(SPI_BASE->DR) = tx_data;
// Wait for RXNE to set -> This will indicate that the Rx buffer is not empty
while (!(SPI_BASE->SR &SPI_SR_RXNE));
// TODO: test read!
return *(uint8_t*)&(SPI_BASE->DR);
}
// Interrupt Service Routines
void SPI1_IRQHandle()
{
//HANDLE_INT_FLAG(SPI1->SR, );
}
void SPI2_IRQHandle()
{
}

@ -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_ */

@ -23,8 +23,6 @@ SOFTWARE.
*/
#include "max31865.h"
#include <stdint.h>
#include <stdbool.h>
enum REG{
REG_READ_CONFIGURATION = 0x00,
@ -60,39 +58,30 @@ static const float a3 = 0.000000731467;
static const float a4 = 0.000000000691;
static const float a5 = 7.31888555389e-13;
static void _write_n_reg(const max31865_t* device,
uint8_t start_reg_address,
const uint8_t* data,
uint8_t len);
static void _read_n_reg(const max31865_t* device,
uint8_t start_reg_address,
uint8_t* data,
uint8_t len);
void _handle_threshold_fault(const max31865_t* device);
void max31865_init(max31865_t* device,
fptr_b_t chipselect_cb,
u8_fptr_u8_t spi_trx_cb,
fptr_t charged_time_delay_cb,
fptr_t conversion_timer_deay_cb,
fptr_t highFaultThreshold_callback,
fptr_t lowFaultThreshold_callback,
uint16_t rtd_ohm,
uint16_t rref_ohm,
uint16_t lowerFaulThreshold,
uint16_t higherFaultThreshold,
bool wire_3,
bool filter_50Hz)
void max31865_init(
max31865_t* device,
spi_ch_t *spi_ch,
fptr_t charged_time_delay_cb,
fptr_t conversion_timer_deay_cb,
fptr_t highFaultThreshold_callback,
fptr_t lowFaultThreshold_callback,
uint16_t rtd_ohm,
uint16_t rref_ohm,
uint16_t lowerFaulThreshold,
uint16_t higherFaultThreshold,
uint8_t logic_wire_3,
uint8_t logic_filter_50Hz)
{
uint8_t buff[4];
uint8_t temp = 0;
uint16_t temp_1 = 0;
// object setup
device->chipselect = chipselect_cb;
device->spi_trx = spi_trx_cb;
device->charged_time_delay = charged_time_delay_cb;
device->spiCH = spi_ch;
device->charged_time_delay = charged_time_delay_cb;
device->conversion_timer_deay = conversion_timer_deay_cb;
device->highFaultThreshold_cb = highFaultThreshold_callback;
device->lowFaultThreshold_cb = lowFaultThreshold_callback;
@ -101,7 +90,8 @@ void max31865_init(max31865_t* device,
device->lowFaultThreshold = lowerFaulThreshold << 1;
device->highFaultThreshold = higherFaultThreshold << 1;
// settup configurations + set a fault status
device->configReg = (uint8_t)((wire_3 << 4) | (filter_50Hz));
device->configReg = (uint8_t)((logic_wire_3) ? (1 << 4):(0) |
(logic_filter_50Hz) ? (0x01) : (0));
// low and high fault threshold setup
temp_1 = device->highFaultThreshold;
@ -112,8 +102,8 @@ void max31865_init(max31865_t* device,
buff[3] = (uint8_t)(temp_1);
temp = device->configReg;
_write_n_reg(device, REG_WRITE_CONFIGURATION, &temp, 1);
_write_n_reg(device, REG_WRITE_HIGH_FAULT_TH_MSB, buff, 4);
spiWriteReg(device->spiCH,REG_WRITE_CONFIGURATION, temp);
spiWriteBlock(device->spiCH, REG_WRITE_HIGH_FAULT_TH_MSB, buff,4);
}
uint16_t max31865_readADC(const max31865_t* device)
@ -122,26 +112,26 @@ uint16_t max31865_readADC(const max31865_t* device)
uint8_t temp = 0;
// turn on vbias
temp = device->configReg | D7;
_write_n_reg(device, REG_WRITE_CONFIGURATION, &temp, 1);
spiWriteReg(device->spiCH, REG_WRITE_CONFIGURATION,temp);
device->charged_time_delay();
// initiate 1-shot conversion + vbias
temp = device->configReg | 0xA0;
_write_n_reg(device, REG_WRITE_CONFIGURATION, &temp, 1);
spiWriteReg(device->spiCH, REG_WRITE_CONFIGURATION,temp);
device->conversion_timer_deay();
_read_n_reg(device, REG_READ_RTD_MSB, &buff, 2);
spiAutoReadBlock(device->spiCH, REG_READ_RTD_MSB, buff, 2);
// turn off vbias
_write_n_reg(device, REG_WRITE_CONFIGURATION, &(device->configReg), 1);
spiWriteReg(device->spiCH, REG_WRITE_CONFIGURATION, device->configReg);
if(buff[1] & 0x01) {
_handle_threshold_fault(device);
}
return ((uint16_t)((buff[0]<<8) | (buff[1] >> 1)) );
}
@ -172,8 +162,7 @@ void max31865_setHighFaultThreshold(max31865_t* device,
threshold = threshold << 1;
buff[0] = (uint8_t)(threshold >> 8);
buff[1] = (uint8_t)(threshold);
_write_n_reg(device, REG_WRITE_HIGH_FAULT_TH_MSB, buff, 2);
spiWriteBlock(device->spiCH, REG_WRITE_HIGH_FAULT_TH_MSB,buff,2);
}
void max31865_setLowFaultThreshold(max31865_t* device,
@ -185,13 +174,13 @@ void max31865_setLowFaultThreshold(max31865_t* device,
threshold = threshold << 1;
buff[0] = (uint8_t)(threshold >> 8);
buff[1] = (uint8_t)(threshold);
_write_n_reg(device, REG_WRITE_LOW_FAULT_TH_MSB, buff, 2);
spiWriteBlock(device->spiCH, REG_WRITE_LOW_FAULT_TH_MSB,buff,2);
}
int8_t max31865_checkThresholdFault(const max31865_t* device)
{
uint8_t buff;
_read_n_reg(device,REG_READ_FAULT_STATUS, &buff, 1);
buff = spiReadReg(device->spiCH, REG_READ_FAULT_STATUS);
if(buff & max31865_err_RTD_HIGH_THRESHOLD) return 1;
if(buff & max31865_err_RTD_LOW_THRESHOLD) return -1;
@ -202,55 +191,13 @@ int8_t max31865_checkThresholdFault(const max31865_t* device)
uint8_t max31865_readFault(const max31865_t* device)
{
uint8_t buff;
_read_n_reg(device, REG_READ_FAULT_STATUS, &buff, 1);
return buff;
return spiReadReg(device->spiCH, REG_READ_FAULT_STATUS);
}
void max31865_clearFault(const max31865_t* device)
{
uint8_t temp = (device->configReg | D1);
_write_n_reg(device,REG_WRITE_CONFIGURATION, &temp, 1);
}
static void _write_n_reg(const max31865_t* device,
uint8_t start_reg_address,
const uint8_t* data,
uint8_t len)
{
uint8_t index = 0;
if(len == 0) return;
device->chipselect(true);
device->spi_trx(start_reg_address);
do{
device->spi_trx(data[index++]);
} while(index < len);
device->chipselect(false);
}
static void _read_n_reg(const max31865_t* device,
uint8_t start_reg_address,
uint8_t* data,
uint8_t len)
{
uint8_t index = 0;
if(len == 0) return;
device->chipselect(true);
device->spi_trx(start_reg_address);
do {
data[index++] = device->spi_trx(0xFF);
} while(index < len);
device->chipselect(false);
spiWriteReg(device->spiCH, REG_WRITE_CONFIGURATION, temp);
}
void _handle_threshold_fault(const max31865_t* device)

@ -26,10 +26,10 @@ SOFTWARE.
#define MAX31865_H_
#include <stdint.h>
#include <stdbool.h>
#include "pin.h"
#include "spi.h"
typedef void (*fptr_t)(void);
typedef void (*fptr_b_t)(bool);
typedef uint8_t (*u8_fptr_u8_t)(uint8_t);
typedef enum{
@ -42,9 +42,8 @@ typedef enum{
}max31865_err_t;
typedef struct{
fptr_b_t chipselect;
u8_fptr_u8_t spi_trx;
fptr_t charged_time_delay;
spi_ch_t *spiCH;
fptr_t charged_time_delay;
fptr_t conversion_timer_deay;
fptr_t highFaultThreshold_cb;
fptr_t lowFaultThreshold_cb;
@ -55,36 +54,44 @@ typedef struct{
uint8_t configReg;
}max31865_t;
void max31865_init(max31865_t* device,
fptr_b_t chipselect_cb,
u8_fptr_u8_t spi_trx_cb,
fptr_t charged_time_delay_cb,
fptr_t conversion_timer_deay_cb,
fptr_t highFaultThreshold_callback,
fptr_t lowFaultThreshold_callback,
uint16_t rtd_ohm,
uint16_t rref_ohm,
uint16_t lowerFaulThreshold,
uint16_t higherFaultThreshold,
bool wire_3,
bool filter_50Hz);
uint16_t max31865_readADC(const max31865_t* device);
float max31865_readRTD_ohm(const max31865_t* device);
float max31865_readCelsius(const max31865_t* device);
void max31865_setHighFaultThreshold(max31865_t* device,
uint16_t threshold);
void max31865_setLowFaultThreshold(max31865_t* device,
uint16_t threshold);
int8_t max31865_checkThresholdFault(const max31865_t* device);
uint8_t max31865_readFault(const max31865_t* device);
void max31865_clearFault(const max31865_t* device);
void max31865_init(
max31865_t* device,
spi_ch_t *spi_ch,
fptr_t charged_time_delay_cb,
fptr_t conversion_timer_deay_cb,
fptr_t highFaultThreshold_callback,
fptr_t lowFaultThreshold_callback,
uint16_t rtd_ohm,
uint16_t rref_ohm,
uint16_t lowerFaulThreshold,
uint16_t higherFaultThreshold,
uint8_t logic_wire_3,
uint8_t logic_filter_50Hz);
uint16_t max31865_readADC(
const max31865_t *device);
float max31865_readRTD_ohm(
const max31865_t *device);
float max31865_readCelsius(
const max31865_t *device);
void max31865_setHighFaultThreshold(
max31865_t *device,
uint16_t hreshold);
void max31865_setLowFaultThreshold(
max31865_t *device,
uint16_t threshold);
int8_t max31865_checkThresholdFault(
const max31865_t *device);
uint8_t max31865_readFault(
const max31865_t *device);
void max31865_clearFault(
const max31865_t *device);
#endif /* MAX31865_H_ */

@ -0,0 +1,124 @@
#include "max7219.h"
void max7219_init(
max7219_t *display,
spi_ch_t *spi_ch)
{
display->spiCH = spi_ch;
}
void max7219_testDisplay(
max7219_t *display,
uint8_t logic)
{
spiWriteReg(display->spiCH,0x0F, (logic) ? 0x01 : 0x00);
}
void max7219_shutdownDiaply(
max7219_t *display,
uint8_t logic)
{
spiWriteReg(display->spiCH,0x0C, (logic) ? 0x00 : 0x01);
}
void max7219_setDecodeMode(
max7219_t *display,
max7219_decodeMode_t dmode)
{
spiWriteReg(display->spiCH,0x09,(uint8_t) dmode);
}
void max7219_setIntensity(
max7219_t *display,
uint8_t intensity)
{
spiWriteReg(display->spiCH, 0x0A, intensity & 0x0F);
}
void max7219_setScanLimit(
max7219_t *display,
max7219_scanLimit_t slimit)
{
spiWriteReg(display->spiCH, 0x0B, ((uint8_t) slimit) & 0x0F);
}
void max7219_setAllLEDsOff(
max7219_t *display)
{
uint8_t i;
for(i = 0; i < 9; i++) {
spiWriteReg(display->spiCH, i, 0x00);
}
}
void max7219_ledMatrixSetLED(
max7219_t *display,
uint8_t row,
uint8_t col)
{
//uint8_t val = 0xAE; // Unused variable warning commented by KeY
row = (row & 0x07) + 1;
col = 1 << (col & 0x07);
spiWriteReg(display->spiCH, row,col);
}
void max7219_rawWrite(
max7219_t *display,
uint8_t reg,
uint8_t data)
{
spiWriteReg(display->spiCH, reg, data);
}
void max7219_printLedMatrix(
max7219_t *display,
uint8_t matrix[])
{
uint8_t i = 0;
for(i = 0; i < 8; i ++) {
spiWriteReg(display->spiCH, i+1, matrix[i]);
}
}
void max7219_ledMatrixUnsetLED(
max7219_t *display,
uint8_t row,
uint8_t col)
{
row = (row & 0x07) + 1;
col = 1 << (col & 0x07);
// TODO: find out how to turn off LED
spiWriteReg(display->spiCH, row,col+1);
}
#if 0
// daysichained matrix
typedef struct{
spi_ch_t *spiCH;
uint8_t nDevices;
}max7219_dm_t;
void max7219_dm_write(
max7219_dm_t *matrix,
uint8_t **data)
{
uint8_t i = 0;
uint8_t j = 0;
// TODO: Test it out
for(i = 0; i < 8; i++) {
pinWrite(matrix->spiCH->pin, 0);
for(j = 0; j < matrix->nDevices; j++) {
spiTrx8BitPolling(matrix->spiCH->spi, i+1); // reg
spiTrx8BitPolling(matrix->spiCH->spi, data[j][i]);
}
pinWrite(matrix->spiCH->pin, 1);
}
}
#endif

@ -0,0 +1,111 @@
/**
**************************************************************************************************
* @file max7219.h
* @author Kerem Yollu & Edwin Koch
* @date 25.08.2022
* @version 1.0
**************************************************************************************************
* @brief
*
* **Detailed Description :**
*
* @todo
**************************************************************************************************
*/
#ifndef _MAX7219_H_
#define _MAX7219_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "spi.h"
#include "pin.h"
typedef enum{
NO_DECODE_DIGIT_7_TO_0 = 0x00,
CODE_B_DECODE_ONLY_DIGIT_0 = 0x01,
CODE_B_DECODE_ONLY_DIGIT_3_TO_0 = 0x0F,
CODE_B_DECOD_DIGIT_7_TO_0 = 0xFF
}max7219_decodeMode_t;
typedef enum{
DISPLAY_DIGIT_0 = 0x00,
DISPLAY_DIGIT_1_TO_0 = 0x01,
DSIPLAX_DIGIT_2_TO_0 = 0x02,
DSIPLAX_DIGIT_3_TO_0 = 0x03,
DSIPLAX_DIGIT_4_TO_0 = 0x04,
DSIPLAX_DIGIT_5_TO_0 = 0x05,
DSIPLAX_DIGIT_6_TO_0 = 0x06,
DSIPLAX_DIGIT_7_TO_0 = 0x07
}max7219_scanLimit_t;
typedef struct{
spi_ch_t *spiCH;
}max7219_t;
void max7219_init(
max7219_t *display,
spi_ch_t *spi_ch);
void max7219_testDisplay(
max7219_t *display,
uint8_t logic);
void max7219_shutdownDiaply(
max7219_t *display,
uint8_t logic);
void max7219_setDecodeMode(
max7219_t *display,
max7219_decodeMode_t dmode);
void max7219_setIntensity(
max7219_t *display,
uint8_t intensity);
void max7219_setScanLimit(
max7219_t *display,
max7219_scanLimit_t slimit);
void max7219_setAllLEDsOff(
max7219_t *display);
void max7219_ledMatrixSetLED(
max7219_t *display,
uint8_t row,
uint8_t col);
void max7219_rawWrite(
max7219_t *display,
uint8_t reg,
uint8_t data);
void max7219_printLedMatrix(
max7219_t *display,
uint8_t matrix[]);
void max7219_ledMatrixUnsetLED(
max7219_t *display,
uint8_t row,
uint8_t col);
#if 0
// daysichained matrix
typedef struct{
spi_ch_t *spiCH;
uint8_t nDevices;
}max7219_dm_t;
void max7219_dm_write(
max7219_dm_t *matrix,
uint8_t **data);
#endif
#ifdef _cplusplus
}
#endif
#endif // _MAX7219_H_

@ -0,0 +1,126 @@
#include "max7219.h"
void max7219_init(
max7219_t *display,
spi_ch_t *spi_ch)
{
display->spiCH = spi_ch;
}
void h
void max7219_testDisplay(
max7219_t *display,
uint8_t logic)
{
spiWriteReg(display->spiCH,0x0F, (logic) ? 0x01 : 0x00);
}
void max7219_shutdownDiaply(
max7219_t *display,
uint8_t logic)
{
spiWriteReg(display->spiCH,0x0C, (logic) ? 0x00 : 0x01);
}
void max7219_setDecodeMode(
max7219_t *display,
max7219_decodeMode_t dmode)
{
spiWriteReg(display->spiCH,0x09,(uint8_t) dmode);
}
void max7219_setIntensity(
max7219_t *display,
uint8_t intensity)
{
spiWriteReg(display->spiCH, 0x0A, intensity & 0x0F);
}
void max7219_setScanLimit(
max7219_t *display,
max7219_scanLimit_t slimit)
{
spiWriteReg(display->spiCH, 0x0B, ((uint8_t) slimit) & 0x0F);
}
void max7219_setAllLEDsOff(
max7219_t *display)
{
uint8_t i;
for(i = 0; i < 9; i++) {
spiWriteReg(display->spiCH, i, 0x00);
}
}
void max7219_ledMatrixSetLED(
max7219_t *display,
uint8_t row,
uint8_t col)
{
uint8_t val = 0xAE;
row = (row & 0x07) + 1;
col = 1 << (col & 0x07);
spiWriteReg(display->spiCH, row,col);
}
void max7219_rawWrite(
max7219_t *display,
uint8_t reg,
uint8_t data)
{
spiWriteReg(display->spiCH, reg, data);
}
void max7219_printLedMatrix(
max7219_t *display,
uint8_t matrix[])
{
uint8_t i = 0;
for(i = 0; i < 8; i ++) {
spiWriteReg(display->spiCH, i+1, matrix[i]);
}
}
void max7219_ledMatrixUnsetLED(
max7219_t *display,
uint8_t row,
uint8_t col)
{
row = (row & 0x07) + 1;
col = 1 << (col & 0x07);
// TODO: find out how to turn off LED
spiWriteReg(display->spiCH, row,col+1);
}
#if 0
// daysichained matrix
typedef struct{
spi_ch_t *spiCH;
uint8_t nDevices;
}max7219_dm_t;
void max7219_dm_write(
max7219_dm_t *matrix,
uint8_t **data)
{
uint8_t i = 0;
uint8_t j = 0;
// TODO: Test it out
for(i = 0; i < 8; i++) {
pinWrite(matrix->spiCH->pin, 0);
for(j = 0; j < matrix->nDevices; j++) {
spiTrx8BitPolling(matrix->spiCH->spi, i+1); // reg
spiTrx8BitPolling(matrix->spiCH->spi, data[j][i]);
}
pinWrite(matrix->spiCH->pin, 1);
}
}
#endif

@ -0,0 +1,160 @@
/**
**************************************************************************************************
* @file max7219.h
* @author Kerem Yollu & Edwin Koch
* @date 25.08.2022
* @version 1.0
**************************************************************************************************
* @brief
*
* **Detailed Description :**
*
* @todo
**************************************************************************************************
*/
#ifndef _MAX7219_H_
#define _MAX7219_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "spi.h"
#include "pin.h"
typedef enum{
NO_DECODE_DIGIT_7_TO_0 = 0x00,
CODE_B_DECODE_ONLY_DIGIT_0 = 0x01,
CODE_B_DECODE_ONLY_DIGIT_3_TO_0 = 0x0F,
CODE_B_DECOD_DIGIT_7_TO_0 = 0xFF
}max7219_decodeMode_t;
typedef enum{
DISPLAY_DIGIT_0 = 0x00,
DISPLAY_DIGIT_1_TO_0 = 0x01,
DSIPLAX_DIGIT_2_TO_0 = 0x02,
DSIPLAX_DIGIT_3_TO_0 = 0x03,
DSIPLAX_DIGIT_4_TO_0 = 0x04,
DSIPLAX_DIGIT_5_TO_0 = 0x05,
DSIPLAX_DIGIT_6_TO_0 = 0x06,
DSIPLAX_DIGIT_7_TO_0 = 0x07
}max7219_scanLimit_t;
/**
* @brief max7219 matrix class
*
* The matrix can be ccomposed of only one ore many devices daysichained
* together.
* @var *spiCH Pointer to spi channel object
* @var nDevicesChained Ammount of devices hoocked up together
* @var brightness brightness of the matrix
* @var buf Array of matrix content. Each n to n + 7 (n can be 0, 8, 16, etc) represents the
* content of one individual max7219 device.
*/
typedef struct{
spi_ch_t *spiCH;
uint8_t nDevicesChained;
uint8_t brightness;
uint8_t buf[];
}max7219_mx_t;
void max7219_t_mx_init(
max7219_mx_t *matrix,
spi_ch_t *spiChannel,
uint8_t *pBuf,
uint8_t bufLen);
void max7219_mx_setPixel(
max7219_mx_t *matrix,
uint8_t row,
uint8_t col,
uint8_t logic);
void max7219_mx_print(
max7219_mx_t *matrix,
char *text,
uint8_t len);
void max7219_mx_show(
max7219_mx_t *matrix);
void max7219_mx_shutdown(
max7219_mx_t *matrix);
void max7219_mx_test(
max7219_mx_t *matrix);
void max7219_mx_mapMatrix(
max7219_mx_t *matrix,
uint8_t *map);
/*
void max7219_init(
max7219_t *display,
spi_ch_t *spi_ch);
void max7219_testDisplay(
max7219_t *display,
uint8_t logic);
void max7219_shutdownDiaply(
max7219_t *display,
uint8_t logic);
void max7219_setDecodeMode(
max7219_t *display,
max7219_decodeMode_t dmode);
void max7219_setIntensity(
max7219_t *display,
uint8_t intensity);
void max7219_setScanLimit(
max7219_t *display,
max7219_scanLimit_t slimit);
void max7219_setAllLEDsOff(
max7219_t *display);
void max7219_ledMatrixSetLED(
max7219_t *display,
uint8_t row,
uint8_t col);
void max7219_rawWrite(
max7219_t *display,
uint8_t reg,
uint8_t data);
void max7219_printLedMatrix(
max7219_t *display,
uint8_t matrix[]);
void max7219_ledMatrixUnsetLED(
max7219_t *display,
uint8_t row,
uint8_t col);
#if 0
// daysichained matrix
typedef struct{
spi_ch_t *spiCH;
uint8_t nDevices;
}max7219_dm_t;
void max7219_dm_write(
max7219_dm_t *matrix,
uint8_t **data);
#endif
*/
#ifdef _cplusplus
}
#endif
#endif // _MAX7219_H_

Binary file not shown.

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

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

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

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

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

@ -863,13 +863,8 @@ WARN_LOGFILE =
# directories like /usr/src/myproject. Separate the files or directories with
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
# KeY
INPUT = @CMAKE_CURRENT_SOURCE_DIR@/ \
@CMAKE_CURRENT_SOURCE_DIR@/bsl/csl/interfaces/ \
@CMAKE_CURRENT_SOURCE_DIR@/bsl/csl/stm32f042/Drivers/CMSIS/Device/ST/STM32F0xx/Include/ \
@CMAKE_CURRENT_SOURCE_DIR@/bsl/csl/stm32f042/Src/ \
@CMAKE_CURRENT_SOURCE_DIR@/bsl/csl/stm32f042/Device/
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@ -948,7 +943,7 @@ FILE_PATTERNS = *.c \
# be searched for input files as well.
# The default value is: NO.
RECURSIVE = NO
RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a

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

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

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

Binary file not shown.

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)

@ -0,0 +1,95 @@
{
"organization": "freeCodeCamp",
"website": "https://www.freecodecamp.org/",
"formed": 2014,
"founder": "Quincy Larson",
"certifications": [
{
"name": "Responsive Web Design",
"courses": [
"HTML",
"CSS"
]
},
{
"name": "JavaScript Algorithms and Data Structures",
"courses": [
"JavaScript"
]
},
{
"name": "Front End Development Libraries",
"courses": [
"Bootstrap",
"jQuery",
"Sass",
"React",
"Redux"
]
},
{
"name": "Data Visualization",
"courses": [
"D3"
]
},
{
"name": "Relational Database Course",
"courses": [
"Linux",
"SQL",
"PostgreSQL",
"Bash Scripting",
"Git and GitHub",
"Nano"
]
},
{
"name": "Back End Development and APIs",
"courses": [
"MongoDB",
"Express",
"Node",
"NPM"
]
},
{
"name": "Quality Assurance",
"courses": [
"Testing with Chai",
"Express",
"Node"
]
},
{
"name": "Scientific Computing with Python",
"courses": [
"Python"
]
},
{
"name": "Data Analysis with Python",
"courses": [
"Numpy",
"Pandas",
"Matplotlib",
"Seaborn"
]
},
{
"name": "Information Security",
"courses": [
"HelmetJS"
]
},
{
"name": "Machine Learning with Python",
"courses": [
"Machine Learning",
"TensorFlow"
]
}
]
}

@ -0,0 +1,9 @@
import json
with open('config.json', 'r') as config_file:
config_data = json.load(config_file)
# print(config_data)
# print(json.dumps(config_data, indent=4))
print(json.dumps(config_data, indent=4, sort_keys=True))

26
ked/$

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

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

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

@ -1,90 +0,0 @@
/**
**************************************************************************************************
* @file i2c.h
* @author Kerem Yollu & Edwin Koch
* @date 18.07.2022
* @version 1.0
**************************************************************************************************
* @brief I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips :
* following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA
* This will also not have a I3C support for the forseable futrue.
*
* **Detailed Description :**
*
* I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips :
* following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA
* This will also not have a I3C support for the forseable futrue.
*
* @todo
* - 18.07.2021 : Implement the i2c.c.
**************************************************************************************************
*/
#ifndef _I2C_H_
#define _I2C_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#define I2C_STATE_RESET 1 // Not Initialized
#define I2C_STATE_READY 2 // Ready
#define I2C_STATE_TX 4 // Transmitting
#define I2C_STATE_RX 5 // Receiving
#define I2C_STATE_LISTEN 6 // Listening
#define I2C_STATE_ABORT 7 // Aborted by user
#define I2C_STATE_TIMEOUT 8 // Timeout
#define I2C_STATE_ERROR 9 // Error happened
#define I2C_SPEED_STANDART 1 // Sm 100 kbits/s This mode will be choosen for the constructor.
#define I2C_SPEED_FAST 2 // Fm 400 kbits/s
#define I2C_SPEED_FAST_PLUS 3 // Fm+ 1 Mbits/s
#define I2C_SPEED_HIGH_SPEED 4 // Hs 3.4 Mbits/s
#define I2C_SPEED_ULTRA_FAST 5 // UFm 5 Mbits/s
#define I2C_ADDRESS_7B 1 // 7 bits addressing mode
#define I2C_ADDRESS_10B 2 // 10 bits addressing mode
#define I2C_MODE_MASTER 1 // Single Master Mode
#define I2C_MODE_SLAVE 2 // Slave Mode
#define I2C_MODE_MULTI_MASTER 3 // Multy Master Mode
/* Creator from the CPP Version PLease keep it to define the main init sequence.*/
//ll_i2c(uint16_t address, uint8_t channel, uint8_t mode, uint8_t adressMode); // Creat i2c abject witha agiven channel address & mode speed is by default the slowest.
void i2cRead(uint8_t *reg, uint8_t *buffer, uint8_t &regLenght, uint8_t &bufferLenght); // Defined by me : Read a given number of bytes
void i2cWrite(uint8_t *reg, uint8_t *data, uint8_t &regLenght, uint8_t &dataLenght); // Defined by me : Send a given number of bytes
uint8_t i2cTestDeviceSpeed(); // Defined by me : Cycle trough different modes until device cnat't answer fast enought
uint8_t i2cDiscoverDevices(); // Defined by me : Scan the awailable address range on standart mode to find devices
void i2cInitChannelAsMaster(); // Hardware Specific : Initilise the hardware channel in master mode
void i2cInitChannelAsSlave(); // Hardware Specific : Initilise the hardware channel in slavic mode (@life of boris)
void i2cFreeChannel(); // Hardware Specific : Free the hardware channel for othe recousrces
void i2cClockSynchronise();// I2C Standart : Clock Syncronization
void i2cReadDeviceInfo(); // I2c Standart : 3 Bytes (24 bits) | 12 Bits : Manufacturer info | 9 Bits: Part Identification | 3 Bits DIE Rev.
void i2cAbortTransmit(); // I2c Standart : Stop Communication for multimaster mode
void i2cClockStretch(); // I2C Standart : Optional For Pausing Communication because treatement takes longer than the communication
void i2cArbitration(); // I2C Standart : Arbitration for multimaster mode to define the right master.
void i2cSoftReset(); // I2C Standart : Software reset not supported by all hardware.
void i2cBusClear(); // I2C Standart : in case if SCL is stuck
void i2cSetSpeed(uint8_t speed); // I2C Standart
void i2cSetAddress(uint16_t &address); // I2C Standart
void i2cSetAddressMode(); // I2C Standart
void i2cSetTimeout(uint8_t &timeout); // Hardware specific
void i2cSetInterrupt(); // Hardware Specific
void i2cSetDma(); // Hardware specific
void i2cThrowError(int16_t error); // Defined by me : Private error function for error handling
void i2cPointReg(uint8_t *reg); // Defined by me : Points to the register to be red from
#ifdef __cplusplus
}
#endif
#endif // _I2C_H_

@ -1,45 +0,0 @@
/**
**************************************************************************************************
* @file spi.h
* @author Kerem Yollu & Edwin Koch
* @date 12.03.2022
* @version 1.0
**************************************************************************************************
* @brief This is the genral interface for spi.
*
* **Detailed Description :**
* This the spi interface and belongs to the interface layer.
*
**************************************************************************************************
*/
#ifndef _SPI_H_
#define _SPI_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "hardwareDescription.h"
/** This is the spi hardware channel class*/
void spi_init(spiCH_t spi_hw_ch);
/*!
* @brief Transmits and receives on byte of data
* @param spi_hw_ch SPI hardware channel
* @param tx_data 'tx_data' The byte to be transmitted"
* @return The received data
*/
uint8_t spi_trx(spiCH_t spi_hw_ch, uint8_t tx_data);
#ifdef __cplusplus
}
#endif
#endif // _SPI_H_

@ -1,25 +0,0 @@
#ifndef _SPI_HPP_
#define _SPI_HPP_
#include <stdint.h>
template <typename Derived>
struct SPI
{
uint8_t trx_u8(const uint8_t& data)
{
return static_cast<Derived*>(this)->trx_u8Impl(data);
}
void tx(const uint8_t& data)
{
static_cast<Derived*>(this)->txImpl(data);
}
uint8_t rx()
{
return static_cast<Derived*>(this)->rxImpl();
}
};
#endif // _SPI_HPP_

@ -1,82 +0,0 @@
#ifndef _SPI_CH_H
#define _SPI_CH_H
#ifdef __cplusplus
extern "C" {
#endif
#include "pin.h"
#include "spi.h"
#include <stdint.h>
// https://stackoverflow.com/questions/17052443/c-function-inside-struct
typedef uint8_t (*readReg_t) (uint8_t);
/*! \brief SPI cannel class
* This class cpntains the pin and spi channel number
* select.
* */
typedef struct{
pinNo_t pin, /*!< pin number */
spiCH_t spi /*!< spi hardware channel number */
}spi_ch_t;
/**
* \brief Read register
* Read one byte from a one register with one byte address.
* \param *spi_ch spi pointer to spi channel object
* \param reg_address register address
* \return register content
*/
uint8_t spiCH_readReg(spi_ch_t *spi_ch,
uint8_t reg_address);
/**
* \brief Read Block
* Read a block of data starting at a given start address.
* This function makes use of the auto register increment of the device to be read from.
* The address will be sent once and then data is read.
* \param *spi_ch pointer to spi cannel object
* \param start_address start address to the first register
* \param *buffer pointer to the buffer in which the read content is written into
* \param buf_len length of buffer
*/
void spiCH_autoReadBlock(spi_ch_t *spi_ch,
uint8_t start_address,
uint8_t* buffer,
uint8_t buf_len);
/**
* \brief Write register
* Write one byte to one register with one byte address.
* \param *spi_ch pointer to spi channel object
* \param reg_address register address
* \param data data byte to be written into register
*
*/
void spiCH_writeReg(spi_ch_t *spi_ch,
uint8_t reg_address,
uint8_t data);
/**
* \brief Write data block
* Write a block of data starting at a given start address.
* This function makes use of the auto register increment of the device to be written to. The
* address will be sent once an then data is written.
* \param *spi_ch pointer to spi channel object
* \param start_address start address of the first reister
* \param *data pointer to data to be written
* \param data_len length of data to be written
*/
void spiCH_writeBlock(spi_ch_t *spi_ch,
uint8_t start_address,
const uint8_t *data,
uint8_t data_len);
#ifdef __cplusplus
}
#endif
#endif //_SPI_CH_H

@ -1,75 +0,0 @@
#ifndef _SPICH_HPP_
#define _SPICH_HPP_
#include "pin.hpp"
#include "spi.hpp"
// spi channel has a hardware spi object and a pin object for the chipselect.
template <typename DerivedPin,
typename DerivedSPI>
struct SPICH
{
SPICH(Pin<DerivedPin>& csPin,
SPI<DerivedSPI>& spi) :
chipSelect(csPin),
spiHwCH(spi)
{
}
uint8_t read_write_u8(const uint8_t& data)
{
uint8_t temp;
// spiHwCH.takeMutex();
chipSelect.write(false);
temp = spiHwCH.trx_u8(data);
chipSelect.write(true);
// spiHwCH.releaseMutex();
return temp;
}
void readArray(const uint8_t& address,
uint8_t* buffer,
const uint8_t& len)
{
// spiHwCH.takeMutex();
chipSelect.write(false);
spiHwCH.tx(address);
for(uint8_t i = 0; i < len;i++) {
buffer[i] = spiHwCH.rx();
};
chipSelect.write(true);
// spiHwCH.releaseMutex();
}
void writeArray(const uint8_t& address,
const uint8_t* buffer,
const uint8_t& len)
{
chipSelect.write(false);
spiHwCH.tx(address);
for(uint8_t i = 0; i < len; i++) {
spiHwCH.tx(buffer[i]);
};
chipSelect.write(true);
}
private:
// hardware resources
Pin<DerivedPin>& chipSelect;
SPI<DerivedSPI>& spiHwCH;
};
#endif // _SPICH_HPP_

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

@ -1,37 +0,0 @@
add_library(stmDelay delay.c)
target_compile_options(stmDelay PRIVATE ${C_FLAGS})
target_compile_definitions(stmDelay PRIVATE ${C_DEFS})
target_include_directories(stmDelay PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
add_library(sub::delay ALIAS stmDelay)
add_library(stmPin pin.c)
target_compile_options(stmPin PRIVATE ${C_FLAGS})
target_compile_definitions(stmPin PRIVATE ${C_DEFS})
target_include_directories(stmPin PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
add_library(sub::pin ALIAS stmPin)
add_library(stmUsart usart.c)
target_compile_options(stmUsart PRIVATE ${C_FLAGS})
target_compile_definitions(stmUsart PRIVATE ${C_DEFS})
target_include_directories(stmUsart PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
add_library(sub::usart ALIAS stmUsart)
add_library(stmInit deviceSetup.c)
target_compile_options(stmInit PRIVATE ${C_FLAGS})
target_compile_definitions(stmInit PRIVATE ${C_DEFS})
target_include_directories(stmInit PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
add_library(sub::init ALIAS stmInit)
add_library(stmTimer timer.c)
target_compile_options(stmTimer PRIVATE ${C_FLAGS})
target_compile_definitions(stmTimer PRIVATE ${C_DEFS})
target_include_directories(stmTimer PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
add_library(sub::timer ALIAS stmTimer)
add_library(stmSPI spi.c)
target_compile_options(stmSPI PRIVATE ${C_FLAGS})
target_compile_definitions(stmSPI PRIVATE ${C_DEFS})
target_include_directories(stmSPI PUBLIC ${INTERFACES_DIR} ${CSL_INCLUDES})
add_library(sub::spi ALIAS stmSPI)

@ -1,56 +0,0 @@
#include "spi.h"
#define SPI_BASE ((SPI_TypeDef *)spiBase_Addr_List[spi_hw_ch])
// https://controllerstech.com/spi-using-registers-in-stm32/
void spi_init(spiCH_t spi_hw_ch)
{
RCC->APB2ENR |= (1<<12); // Enable SPI1 CLock
SPI1->CR1 |= (1<<0)|(1<<1); // CPOL=1, CPHA=1
SPI1->CR1 |= (1<<2); // Master Mode
SPI1->CR1 |= (3<<3); // BR[2:0] = 011: fPCLK/16, PCLK2 = 80MHz, SPI clk = 5MHz
SPI1->CR1 &= ~(1<<7); // LSBFIRST = 0, MSB first
SPI1->CR1 |= (1<<8) | (1<<9); // SSM=1, SSi=1 -> Software Slave Management
SPI1->CR1 &= ~(1<<10); // RXONLY = 0, full-duplex
SPI1->CR1 &= ~(1<<11); // DFF=0, 8 bit data
SPI1->CR2 = 0;
}
uint8_t spi_trx(spiCH_t spi_hw_ch, uint8_t tx_data)
{
uint8_t data;
// example
while (((SPI1->SR)&(1<<7))); // wait for BSY bit to Reset -> This will indicate that SPI is not busy in communication
SPI1->DR = tx_data; // send data
while (!((SPI1->SR) &(1<<0))); // Wait for RXNE to set -> This will indicate that the Rx buffer is not empty
data = SPI1->DR;
return data;
// implementation 2. step
#if 0
// wait for SPY ready
while((SPI_BASE->SR) & (1 << 7));
// load tx data
SPI_BASE->DR = tx_data;
// Wait for RXNE flag to be set which indicates transmit complete
while(!((SPI_BASE->SR) & (1<<0));
return SPI_BASE->DR;
#endif
}

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

Loading…
Cancel
Save