New organisation with ./ked/run.sh stm32f042k6t6 is now wokring

master
kerem yollu 2 years ago
parent 5de8884257
commit 21f7ecfeb1

@ -23,7 +23,12 @@ set(CMAKE_CORE_DIR ${CMAKE_SOURCE_DIR}/env/cmake_core)
set(CSL_DIR ${CMAKE_SOURCE_DIR}/csl/${CSL_USED}) set(CSL_DIR ${CMAKE_SOURCE_DIR}/csl/${CSL_USED})
# Location of the Sources for the selected CSL -> "Specific to each CSL" # Location of the Sources for the selected CSL -> "Specific to each CSL"
set(CSL_SOURCES ${CMAKE_SOURCE_DIR}/csl/${CSL_USED}/Src) set(CSL_SOURCES ${CSL_DIR}/implementation)
set(CSL_INCLUDES
${CSL_DIR}/CMSIS/Include
${CSL_DIR}/HardwareDescription)
set(CSL_STARTUP ${CSL_DIR}/startup)
# Directiry fot the drivers -> "Common to all CSL" # Directiry fot the drivers -> "Common to all CSL"
set(DRIVERS_DIR ${CMAKE_SOURCE_DIR}/drivers) set(DRIVERS_DIR ${CMAKE_SOURCE_DIR}/drivers)
@ -77,12 +82,11 @@ project(${CSL_USED} ASM C CXX)
#Create the executable #Create the executable
set(EXECUTABLE ${PROJECT_NAME}) set(EXECUTABLE ${PROJECT_NAME})
#################################################################################################### ####################################################################################################
# SUBDIRECTORIES Will add the given folders to the porject an check for CmakeLists.txt # SUBDIRECTORIES Will add the given folders to the porject an check for CmakeLists.txt
#################################################################################################### ####################################################################################################
include(${CSL_DEFS}) include(${CSL_DEFS})
add_subdirectory(csl) add_subdirectory(${CSL_DIR})
#################################################################################################### ####################################################################################################
# Sartupt uCode Definition # Sartupt uCode Definition
@ -107,7 +111,6 @@ foreach(X IN LISTS DRIVERS_LIST)
list(APPEND DRIVER_LIBS ${NEW_DRIVER}) list(APPEND DRIVER_LIBS ${NEW_DRIVER})
endforeach() endforeach()
message("+-------------------------------+") message("+-------------------------------+")
message("${ColourReset}") message("${ColourReset}")

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

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

@ -19,8 +19,7 @@
extern "C" { extern "C" {
#endif #endif
#include "stm32f042x6.h" #include "hardwareDescription.h"
#include <stdint.h>
#define MAX_I2C_CHANNEL_COUNT 1 #define MAX_I2C_CHANNEL_COUNT 1

@ -19,8 +19,7 @@
extern "C" { extern "C" {
#endif #endif
#include "stm32f042x6.h" #include "hardwareDescription.h"
#include <stdint.h>
/*! interrupt types. These act as indexes for the */ /*! interrupt types. These act as indexes for the */
typedef enum { typedef enum {

@ -19,6 +19,8 @@
extern "C" { extern "C" {
#endif #endif
#include "hardwareDescription.h"
#define MAX_N_PORTS_COUNT 3 #define MAX_N_PORTS_COUNT 3
#define MAX_PORT_PINS_COUNT 16 #define MAX_PORT_PINS_COUNT 16
#define MAX_N_PIN_ALT_FUNC 8 #define MAX_N_PIN_ALT_FUNC 8

@ -19,8 +19,7 @@
extern "C" { extern "C" {
#endif #endif
#include "stm32f042x6.h" #include "hardwareDescription.h"
#include <stdint.h>
#define MAX_SPI_CHANNEL_COUNT 2 #define MAX_SPI_CHANNEL_COUNT 2

@ -19,11 +19,24 @@
extern "C" { extern "C" {
#endif #endif
#include "stm32f042x6.h" #include "hardwareDescription.h"
#include <stdint.h>
#define MAX_TIMER_CHANNEL_COUNT 6 #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 * Timer base addresslist of all available timers
* */ * */
@ -37,7 +50,7 @@ static const uint32_t timerBase_Addr_List[MAX_TIMER_CHANNEL_COUNT] = {
}; };
/*! /*!
* RCC clock enabcke bit position for the given register * RCC clock enable bit position for the given register
* */ * */
static const uint8_t timerBus_En_bitPos[MAX_TIMER_CHANNEL_COUNT] = { static const uint8_t timerBus_En_bitPos[MAX_TIMER_CHANNEL_COUNT] = {
RCC_APB2ENR_TIM1EN_Pos, RCC_APB2ENR_TIM1EN_Pos,

@ -19,8 +19,7 @@
extern "C" { extern "C" {
#endif #endif
#include "stm32f042x6.h" #include "hardwareDescription.h"
#include <stdint.h>
#define MAX_USART_CHANNEL_COUNT 2 #define MAX_USART_CHANNEL_COUNT 2

@ -12,16 +12,10 @@ set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_CROSSCOMPILING TRUE) 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 #VARIABLES : defined by user
#################################################################################################### ####################################################################################################
set(LINKER ${CSL_STARTUP}/STM32F042K6Tx_FLASH.ld)
set(CSL_INCLUDES
${UTILS_DIR}
${CMAKE_SOURCE_DIR}/csl/stm32f042/CMSIS/Include
${CMAKE_SOURCE_DIR}/csl/stm32f042/Device)
# For flags please check https://manned.org/arm-none-eabi-gcc/34fd6095 # For flags please check https://manned.org/arm-none-eabi-gcc/34fd6095
set(C_FLAGS set(C_FLAGS

@ -60,19 +60,19 @@ void TIM2_IRQHandler()
if(TIM2->SR & TIM_SR_CC2IF) { if(TIM2->SR & TIM_SR_CC2IF) {
TIM2-> SR &= ~TIM_SR_CC2IF; TIM2-> SR &= ~TIM_SR_CC2IF;
((intHandler_t)(intHandlerList[TIM2_CONTERCOMPARE_2]))(); ((intHandler_t)(intHandlerList[TIM2_COUNTERCOMPARE_2]))();
} }
if(TIM2->SR & TIM_SR_CC3IF) { if(TIM2->SR & TIM_SR_CC3IF) {
TIM2-> SR &= ~TIM_SR_CC3IF; TIM2-> SR &= ~TIM_SR_CC3IF;
((intHandler_t)(intHandlerList[TIM2_CONTERCOMPARE_3]))(); ((intHandler_t)(intHandlerList[TIM2_COUNTERCOMPARE_3]))();
} }
if(TIM2->SR & TIM_SR_CC4IF) { if(TIM2->SR & TIM_SR_CC4IF) {
TIM2-> SR &= ~TIM_SR_CC4IF; TIM2-> SR &= ~TIM_SR_CC4IF;
((intHandler_t)(intHandlerList[TIM2_CONTERCOMPARE_4]))(); ((intHandler_t)(intHandlerList[TIM2_COUNTERCOMPARE_4]))();
} }
if(TIM2->SR & TIM_SR_TIF) { if(TIM2->SR & TIM_SR_TIF) {

@ -0,0 +1,2 @@
set(PERIPHERALS_LIST deviceSetup delay usart timer spi i2c pin interrupt)

@ -0,0 +1,60 @@
/**
**************************************************************************************************
* @file ascii.h
* @author Kerem Yollu
* @date 04.11.2021
* @version 1.0
**************************************************************************************************
* @brief Defines ofr ascii chars.
*
**************************************************************************************************
*/
#ifndef _ASCII_H_
#define _ASCII_H_
#ifdef __cplusplus
extern "C" {
#endif
#define ASCII_NULL 0 // Null character
#define ASCII_SOH 1 // Start of Header
#define ASCII_STX 2 // Start of Text
#define ASCII_ETX 3 // End of Text, hearts card suit
#define ASCII_EOT 4 // End of Transmission, diamonds card suit
#define ASCII_ENQ 5 // Enquiry, clubs card suit
#define ASCII_ACK 6 // Acknowledgement, spade card suit
#define ASCII_BEL 7 // Bell
#define ASCII_BS 8 // Backspace
#define ASCII_HT 9 // Horizontal Tab
#define ASCII_LF 10 // Line feed
#define ASCII_VT 11 // Vertical Tab, male symbol, symbol for Mars
#define ASCII_FF 12 // Form feed, female symbol, symbol for Venus
#define ASCII_CR 13 // Carriage return
#define ASCII_SO 14 // Shift Out
#define ASCII_SI 15 // Shift In
#define ASCII_DLE 16 // Data link escape
#define ASCII_DC1 17 // Device control 1
#define ASCII_DC2 18 // Device control 2
#define ASCII_DC3 19 // Device control 3
#define ASCII_DC4 20 // Device control 4
#define ASCII_NAK 21 // NAK Negative-acknowledge
#define ASCII_SYN 22 // Synchronous idle
#define ASCII_ETB 23 // End of trans. block
#define ASCII_CAN 24 // Cancel
#define ASCII_EM 25 // End of medium
#define ASCII_SUB 26 // Substitute
#define ASCII_ESC 27 // Escape
#define ASCII_FS 28 // File separator
#define ASCII_GS 29 // Group separator
#define ASCII_RS 30 // Record separator
#define ASCII_US 31 // Unit separator
#define ASCII_DEL 127 // Delete
#define ASCII_space 32 // Space
#define ASCII_nbsp 255 // Non-breaking space or no-break space
#define ASCII_clear "\033[2J" // Clear screen command
#ifdef __cplusplus
}
#endif
#endif // _ASCII_H_

@ -0,0 +1,16 @@
#ifndef _DELAY_H_
#define _DELAY_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
void delayMs(uint16_t delay);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,24 @@
#ifndef _DEVICE_SETUP_H_
#define _DEVICE_SETUP_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t systemCoreClock; /*!< System Clock Frequency (Core Clock) */
void setupInit();
void setupClock();
void setupBus();
void setupPower();
void setupMemory();
void delayInitMs(uint32_t clk, uint32_t ticks);
#ifdef __cplusplus
}
#endif
#endif /* _DEVICE_SETUP_H_ */

@ -0,0 +1,121 @@
#include "i2c.h"
#include "usart.h"
void i2c_init( i2c_t *i2c_dev, /*!< Pointer to I2C hardware Object */
i2cCh_t channelNo, /*!< The harware channel to be used */
i2c_mode_t mode, /*!< Master, Slave or Multymaster Modes */
uint16_t mainAddress, /*!< First and Main address of the device */
uint16_t secondAddress, /*!< Second address if dual addresse mode is configured */
i2c_address_count_t addressCount, /*!< Single or multiple */
i2c_address_size_t addressSize, /*!< 10 or 7 bit address size */
i2c_clk_speed_t speed, /*!< Bus Speed */
i2c_clk_stretching_t stretching, /*!< Clock Stretching enable onyl in slave mode */
i2c_wake_types_t wakeOn /*!< Wake up condition */
)
{
i2c_dev->channelNo = channelNo;
i2c_dev->mode = mode;
i2c_dev->mainAddress = mainAddress;
i2c_dev->secondAddress = secondAddress;
i2c_dev->addressCount = addressCount;
i2c_dev->addressSize = addressSize;
i2c_dev->speed = speed;
i2c_dev->stretching = stretching;
i2c_dev->wakeOn = wakeOn;
//Initial state States
i2c_dev->hardwareState = i2c_hw_disabled;
i2c_dev->periferalState = i2c_perif_disabled;
i2c_hardware_enable(i2c_dev);
i2c_periferal_disable(i2c_dev); // Just to be sure as periferal configuration can not be dont when active.
i2c_set_filter(i2c_dev,1);
i2c_set_clk_stretch(i2c_dev, stretching);
i2c_set_clk_speed(i2c_dev, speed);
i2c_set_mode(i2c_dev, mode);
i2c_set_address_lenght(i2c_dev, addressSize);
i2c_set_address(i2c_dev, mainAddress);
i2c_set_address_second(i2c_dev, mainAddress);
i2c_periferal_enable(i2c_dev);
print_Usart(usart2, "\n\rI2C -> periferal enabled\n\r");
}
void i2c_read(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
{
i2c_dev->periferalState = i2c_perif_read;
// Arch nemesis ! We only setn the address
// but the counter allso socunt the bits that we have recieved
// and we want to read one byte
// every transaction counts
i2c_set_transfer_counter(i2c_dev,1);
i2c_send_address_for_write(i2c_dev, slaveAddress);
i2c_send_reg_address(i2c_dev, registerAddress);
while(!i2c_is_transfer_complete(i2c_dev));
//i2c_set_transfer_counter(i2c_dev,2);
i2c_send_address_for_read(i2c_dev, slaveAddress);
i2c_get_input_register(i2c_dev, data);
while(!i2c_is_transfer_complete(i2c_dev));
i2c_send_nack(i2c_dev);
i2c_send_stop(i2c_dev);
while(!i2c_is_perif_ready(i2c_dev));
}
void i2c_write(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
{
uint8_t i = *dataLenght + 1 ;
i2c_dev->periferalState = i2c_perif_write;
i2c_set_transfer_counter(i2c_dev,i);
i2c_send_address_for_write(i2c_dev, slaveAddress);
i2c_send_reg_address(i2c_dev, registerAddress);
for(i = 0; i < *dataLenght; i++)
{
i2c_send_data(i2c_dev, data);
}
while(!i2c_is_transfer_complete(i2c_dev));
i2c_send_stop(i2c_dev);
while(!i2c_is_perif_ready(i2c_dev));
}
uint8_t i2c_check_device(i2c_t *i2c_dev, uint16_t *device)
{
i2c_dev->periferalState = i2c_perif_write;
i2c_set_transfer_counter(i2c_dev,0);
i2c_send_address_for_write(i2c_dev, device);
if(i2c_check_nack(i2c_dev))
{
i2c_dev->hardwareState = i2c_hw_got_nack;
i2c_throw_error(i2c_dev,1);
return 0;
}
i2c_dev->hardwareState = i2c_hw_got_ack;
return 1;
}
uint8_t i2c_discover_devices(i2c_t *i2c_dev)
{
uint16_t i = 0;
for(i = 0x03; i <= 0x77; i++)
{
i2c_check_device(i2c_dev,&i);
}
return 1;
}
void i2c_throw_error(i2c_t *i2c_dev, uint8_t error)
{
print_Usart(usart2, "\n\r");
print_Usart(usart2, "I2C : Error");
print_Usart(usart2, "\n\r");
if(error == 1)
{
print_Usart(usart2, " -> Device not Found ");
print_Usart(usart2, "\n\r");
}
}

@ -0,0 +1,537 @@
/**
**************************************************************************************************
* @file i2c.h
* @author Kerem Yollu & Edwin Koch
* @date 16.02.2023
* @version 1.2
**************************************************************************************************
* @brief I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips :
* following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA
* This will also not have a I3C support for the forseable futrue.
*
* **Detailed Description :**
*
* I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips :
* following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA
* This will also not have a I3C support for the forseable futrue.
*
* @todo
* - 26.07.2021 : Implement DMA
* - 26.07.2021 : Implement Interrupt
* - 26.07.2021 : Implement Sleep/WakeUp
* - 26.07.2021 : Implement Slave opperation
**************************************************************************************************
*/
#ifndef _I2C_H_
#define _I2C_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "hardwareDescription.h"
#include "pin.h"
/*! Enum of possible I2C opperation modes */
typedef enum{
i2c_mode_master, /*!< Master mode : In Master mode, the I2C interface initiates
a data transfer and generates the clock signal. **DEFAULT** */
i2c_mode_multyMaster, /*!< Multimaster Mode : In case if more than one master are present
in one I2C bus. In such case each device needs to be able to
cooperate knowing that another device could talking
therefore the bus is busy (Arbirtation).
For More information : https://www.i2c-bus.org/multimaster/ */
i2c_mode_slave /*!< Slave mode : A slave device has to always be ready to detect and
process a start condition and to recognize its address */
}i2c_mode_t;
/*! Enum of possible I2C speeds */
typedef enum{
i2c_clk_speed_standart, /*!< SM 100 kbits/s Standart i2c Speed **DEFAULT** */
i2c_clk_speed_fast, /*!< FM 400 kbits/s */
i2c_clk_speed_fastPlus, /*!< FM+ 1 Mbits/s */
i2c_clk_speed_hightSpeed, /*!< HS 3.4 Mbits/s */
i2c_clk_speed_ultraFast /*!< UFM 5 Mbits/s */
}i2c_clk_speed_t;
/*! Enum of possible I2C Adress sizes */
typedef enum{
i2c_address_size_7b, /*!< 7 Bits address size **DEFAULT** */
i2c_address_size_10b /*!< 10 Bits address size */
}i2c_address_size_t;
/*! Enum of possible I2C Address count */
typedef enum{
i2c_address_count_single, /*!< Only one address for communication **DEFAULT** */
i2c_address_count_dual /*!< Dual addresses for one device respondng to two addresses */
}i2c_address_count_t;
/*! Enum for clock strechning activation. Can only be implmented as Slave
* for more information : https://www.i2c-bus.org/clock-stretching/ */
typedef enum{
i2c_clk_stretching_disable, /*!< We assume that the master and slave have compatible
Clock frequencies **DEFAULT** */
i2c_clk_stretching_enable /*!< In situations where an I2C slave is not able to co-operate
with the clock speed given by the master and needs to slow down.
This is done by a mechanism referred to as clock stretching. */
}i2c_clk_stretching_t;
/*! Enum for diffenrent wake up methodes wehnin sleep mode */
typedef enum{
i2c_wake_disabled, /*!< No wake up is possible this is the default mode also means that
the sleep function is not implmentes **DEFAULT** */
i2c_wakeUp_address_match /*!< Wakes up on address match, this can be harware dependent */
}i2c_wake_types_t;
/*! typedef for the i2c states*/
typedef enum
{
i2c_hw_disabled, /*!< Hardware Is Disabled */
i2c_hw_reset, /*!< Hardware Is Reseted and in reset mode and need to be initialised */
i2c_hw_enabled, /*!< I2C Hardware is initilized but not neceserly ready */
i2c_hw_ready, /*!< Hardware Initialized and ready for use */
i2c_hw_sent_start, /*!< Generated the star condition */
i2c_hw_out_buff_full, /*!< The output buffer of the I2C Periferal is Full */
i2c_hw_out_buff_empty, /*!< The output buffer of the I2C Periferal is Empty */
i2c_hw_in_buff_full, /*!< The input buffer of the I2C Periferal Is Full */
i2c_hw_in_buff_empty, /*!< The input buffer of the I2C Periferal Is Empty */
i2c_hw_send_read, /*!< Sent read request */
i2c_hw_send_write, /*!< Sent write request */
i2c_hw_got_ack, /*!< Recieved ACK */
i2c_hw_got_nack, /*!< Recieved NACK */
i2c_hw_sent_ack, /*!< Sent ACK */
i2c_hw_sent_nack, /*!< Sent NACK */
i2c_hw_sent_stop, /*!< Generated the star condition */
i2c_hw_error /*!< Error */
} i2c_hw_state_t;
typedef enum
{
i2c_perif_disabled, /*!< Peripheral Is Disabled */
i2c_perif_reset, /*!< Peripheral Is Reseted and in reset mode and need to be initialised */
i2c_perif_enabled, /*!< I2C CHannle is initilized but not neceserly ready */
i2c_perif_ready, /*!< Peripheral Initialized and ready for use */
i2c_perif_address_sent, /*!< The Salve Address Was Sent to the bus */
i2c_perif_write, /*!< The prefiferal is configured for a write */
i2c_perif_read, /*!< The prefiferal is configured for a read */
i2c_perif_rx_ongoing, /*!< Recieving from the bus */
i2c_perif_rx_done, /*!< Recived everything from the bus */
i2c_perif_listening, /*!< Address Listen Mode is ongoing */
i2c_perif_listening_and_tx, /*!< Address Listen Mode and ongoing Data Transmission */
i2c_perif_listening_and_rx, /*!< Address Listen Mode and ongoing Data Reception */
i2c_perif_discovery, /*!< Discovery mode will cancel some error in order to be able to discover the devices on the bus */
i2c_perif_timeout, /*!< Timeout state */
i2c_perif_Error /*!< Error */
} i2c_perif_state_t;
/*! Struture a an i2c channel with all the required propereties*/
typedef struct i2c_t
{
i2cCh_t channelNo; /*!< The harware channel to be used */
i2c_mode_t mode; /*!< Master, Slave or Multymaster Modes */
uint16_t mainAddress; /*!< First and Main address of the device */
uint16_t secondAddress; /*!< Second address if dual addresse mode is configured */
i2c_address_count_t addressCount; /*!< Single or multiple */
i2c_address_size_t addressSize; /*!< 10 or 7 bit address size */
i2c_clk_speed_t speed; /*!< Bus Speed */
i2c_clk_stretching_t stretching; /*!< Clock Stretching enable onyl in slave mode */
i2c_wake_types_t wakeOn; /*!< Define on which type of action the i2c channel should
wake up. Only if de prefiral goes to sleep */
i2c_hw_state_t hardwareState; /*!< The current sitate of the I2C Bus */
i2c_perif_state_t periferalState; /*!< The current sitate of the I2C Bus */
}i2c_t;
/***************************************************************************************************
I2C Configuration functions
***************************************************************************************************/
/**
* @brief Initilize the I2C Hardware
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_init( i2c_t *i2c_dev, /*!< Pointer to I2C hardware Object */
i2cCh_t channelNo, /*!< The harware channel to be used */
i2c_mode_t mode, /*!< Master, Slave or Multymaster Modes */
uint16_t mainAddress, /*!< First and Main address of the device */
uint16_t secondAddress, /*!< Second address if dual addresse mode is configured */
i2c_address_count_t addressCount, /*!< Single or multiple */
i2c_address_size_t addressSize, /*!< 10 or 7 bit address size */
i2c_clk_speed_t speed, /*!< Bus Speed */
i2c_clk_stretching_t stretching, /*!< Clock Stretching enable onyl in slave mode */
i2c_wake_types_t wakeOn /*!< Wake up condition */
);
/**
* @brief De-Initilise the I2C Hardware
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_deinitialise(i2c_t *i2c_dev);
/**
* @brief Set the i2c channle to the gievn mode
* @param Channel is the i2c hardware channel
* @param mode The mode for i2c : Master Slave or Multymaster
*/
void i2c_set_mode(i2c_t *i2c_dev, i2c_mode_t mode);
/**
* @brief Set the i2c channel's address
* @param i2c_dev is the i2c hardware channel
* @param address is the desired address for the device
* @param addressTwo The second address for the device only if dual address mode is not defined
*/
void i2c_set_address(i2c_t *i2c_dev, uint16_t address);
/**
* @brief Set the i2c channel's second address if the hardware allows it
* @param i2c_dev is the i2c hardware channel
* @param address is the desired address for the device
*/
void i2c_set_address_second(i2c_t *i2c_dev, uint16_t address);
/**
* @brief Set the i2c Address Lenght, 7 bit or 8 bit, Master or slave doesn't make any difference
* @param i2c_dev is the i2c hardware channel
* @param size Is the Adress isze to be used 7 Bit or 10 Bit
*/
void i2c_set_address_lenght(i2c_t *i2c_dev, i2c_address_size_t size);
/**
* @brief Stets the Communication speed
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param speed the different awailable speeds
*/
void i2c_set_clk_speed(i2c_t *i2c_dev, i2c_clk_speed_t speed);
/**
* @brief Ebales or disables clock stretching functionalities
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param The value to be written in the register. This will heavily depend on the hardware
*/
void i2c_set_clk_stretch(i2c_t *i2c_dev, i2c_clk_stretching_t stretching);
/**
* @brief Set the wakeup mode
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param wake the desider wakeup mode for now i have found only one mode.
*/
void i2c_set_wakeup(i2c_t *i2c_dev, i2c_wake_types_t wake);
/**
* @brief Configures Hardware implmente filters if there are any.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_set_filter(i2c_t *i2c_dev, uint8_t enable);
/**
* @brief Set the timeout to close the i2c wait time if a communication fails.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param timeout the desider timeout duration in ticks.
*/
void i2c_set_timeout(i2c_t *i2c_dev, uint8_t timeout);
/**
* @brief Resets the i2c Harware and register to it's factory deflauts.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_hardware_reset(i2c_t *i2c_dev);
/**
* @brief Enables I2C Hardware BUS & Clock & Pins
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_hardware_enable(i2c_t *i2c_dev);
/**
* @brief Disables I2C Hardware.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_hardware_disable(i2c_t *i2c_dev);
/**
* @brief Resets the i2c Periferal to it's inital state.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_periferal_reset(i2c_t *i2c_dev);
/**
* @brief Enables I2C Periferal core.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_periferal_enable(i2c_t *i2c_dev);
/**
* @brief Disables I2C Periferal core.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_periferal_disable(i2c_t *i2c_dev);
/**************************************************************************************************
I2C Communication functions independen of opperating mode
***************************************************************************************************/
/**
* @brief Writes the given amount of data to the selected device. This function will
* automaticaly choose between i2cMasterSend(); or i2cSlaveSend();
* Depending if the I2C channel was initiated as slave or master.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data to be written
* @param dataLenght is the total quantity of 8 bit data to be written.
*/
void i2c_write(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
/**
* @brief Reads the given amount of data to the selected device. This function will
* automaticaly choose between i2cMasterRecieve(); or i2cSlaveRecieve();
* Depending if the I2C channel was initiated as slave or master.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data which has been red
* @paran dataLenght is the total quantity of 8 bit data to be red
*/
void i2c_read(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
/**
* @brief Recieve a Single Byte as master from from the given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2c_master_recieve(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Sends a Single Byte as master to the given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the send command will be sent
* @param registerAddress is the regiter to be written to the device
* @param data is the data to be sent
*/
void i2c_master_send(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Recieve a Single Byte as slave from given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2c_slave_recieve(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Recieve a Single Byte as slave from the given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red
*/
void i2c_slave_send(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
/**************************************************************************************************
I2C Hardware functions
***************************************************************************************************/
/**
* @brief Checks if the device is ready for any type of communication
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
uint8_t i2c_is_perif_ready(i2c_t *i2c_dev);
/**
* @brief Generates a Start condition.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_send_start(i2c_t *i2c_dev);
/**
* @brief Generates a Start condition.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_send_stop(i2c_t *i2c_dev);
/**
* @brief Generates a NACK condition.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_send_nack(i2c_t *i2c_dev);
/**
* @brief Checks If a NACK is recieved.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
uint8_t i2c_check_nack(i2c_t *i2c_dev);
/**
* @brief Generates a ACK condition.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_send_ack(i2c_t *i2c_dev);
/**
* @brief Initiates the communication by sending the slave address on the bus followed by a WRITE
* and waits for an ACK (aknowledge)
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress The address of the slave to be communicated
*/
uint8_t i2c_send_address_for_write(i2c_t *i2c_dev, uint16_t *slaveAddress);
/**
* @brief Initiates the communication by sending the slave address on the bus followed by a READ
* and waits for an ACK (aknowledge)
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress The address of the slave to be communicated
*/
uint8_t i2c_send_address_for_read(i2c_t *i2c_dev, uint16_t *slaveAddress);
/**
* @brief Sende the register adrres with which we want to communicate.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param registerAddress The register address of the slave device that we are communication with
*/
void i2c_send_reg_address(i2c_t *i2c_dev, uint8_t *registerAddress);
/**
* @brief Send the register that we want to read or write.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param registerAddress the register that need to be accessed
*/
void i2c_send_data(i2c_t *i2c_dev, uint8_t *data);
/**
* @brief Initiates a Write command with the previously set slave address.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_init_write_command(i2c_t *i2c_dev);
/**
* @brief Initiates a read command with the previously set slave address.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_init_read_command(i2c_t *i2c_dev);
/**
* @brief Is the output buffer full. This also means that there is data present in the ouput buffer
* is sent to the i2c BUS.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
uint8_t i2c_is_output_buffer_full(i2c_t *i2c_dev);
/**
* @brief Is the input buffer full. This also means that there is data present in the input buffer
* is sent to the i2c BUS.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @return 1 when input buffer is full | 0 whenthe input buffer is empty
*/
uint8_t i2c_is_input_buffer_full(i2c_t *i2c_dev);
/**
* @brief reads the I2C input buffer
* is sent to the i2c BUS.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param data pointer to the data that need to be read and returned
*/
void i2c_get_input_register(i2c_t *i2c_dev, uint8_t *data);
/**
* @brief writes to the I2C output buffer
* is sent to the i2c BUS.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param data pointer to the data that need to be read and returned
*/
void i2c_set_output_register(i2c_t *i2c_dev, uint8_t *data);
/**
* @brief Checks if transfer is complete
* is sent to the i2c BUS.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param data pointer to the data that need to be read and returned
* @return 1 when Transefer is complete | 0 When Transfer is ongoing
*/
uint8_t i2c_is_transfer_complete(i2c_t *i2c_dev);
/**
* @brief Defines the amount of transfers to be made. Address exchange and start conditon does not count
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param count amount o data to be transfered.
*/
void i2c_set_transfer_counter(i2c_t *i2c_dev, uint8_t count);
/**
* @brief Defines the amount of transfers to be made. Address exchange and start conditon does not count
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param count amount o data to be transfered.
*/
uint8_t i2c_get_transfer_counter(i2c_t *i2c_dev);
/**************************************************************************************************
I2C Arbitration Functions for Multymaster mode and slaves clock stretching
***************************************************************************************************/
void i2c_arbitrate_clk_sync(); // I2C Standart : Clock Syncronization
void i2c_arbitrate_multymaster_abort_tx(); // I2c Standart : Stop Communication for multimaster mode
void i2c_arbitrate(); // I2C Standart : Arbitration for multimaster mode to define the right master.
void i2c_arbitrate_soft_rst(); // I2C Standart : Software reset not supported by all hardware.
void i2c_arbitration_clear_bus(); // I2C Standart : in case if SCL is stuck
/**************************************************************************************************
I2C Extra functions that are not esential for the main functionality
***************************************************************************************************/
/**
* @brief This function will scan every for possible addresses to discover devices on the bus.
* And write them to the Devices list given to him. This function will not discover more
* devices than what he is told.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
uint8_t i2c_discover_devices(i2c_t *i2c_dev);
/**
* @brief This function will scan the given device to see if he responds
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param address is the address to be chekced
*/
uint8_t i2c_check_device(i2c_t *i2c_dev, uint16_t *device);
/**
* @brief This function will try to communicate with a device with every speed
* allowed by his hardware to find out the maximum communication sppeed possible.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to which the read command will be sent
*/
i2c_clk_speed_t i2c_test_bus_speed(i2c_t *i2c_dev, uint16_t *slaveAddress);
/**
* @brief This function will read the device info register (if awailable) as follows :
* I2c Standart : 3 Bytes (24 bits) | 12 Bits : Manufacturer info | 9 Bits: Part Identification | 3 Bits DIE Rev.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
* @param slaveAddress is the address of the device to be red
*/
uint32_t i2c_get_device_info(i2c_t *i2c_dev, uint16_t *slaveAddress);
/**
* @brief The selected i2c channel is put on sleep.
* @param i2c_dev is the beforehand declared i2c channel with his opperation modes
*/
void i2c_sleep(i2c_t *i2c_dev);
/**
* @brief Error handling.
* @param error The error no generated.
*/
void i2c_throw_error(i2c_t *i2c_dev, uint8_t error);
uint8_t i2c_is_txis(i2c_t *i2c_dev);
#ifdef __cplusplus
}
#endif
#endif // _I2C_H_

@ -0,0 +1,2 @@
#include "interrupt.h"

@ -0,0 +1,98 @@
/**
**************************************************************************************************
* @file interrupt.h
* @author Kerem Yollu & Edwin Koch
* @date 30.10.2022
* @version 1.0
**************************************************************************************************
* @brief This is the genral interface for interrupts.
*
* **Detailed Description :**
* This the spi interface and belongs to the interface layer.
*
**************************************************************************************************
*/
#ifndef _INTERRUPT_H_
#define _INTERRUPT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "hardwareDescription.h"
/*! interrupt callback type for the handler */
typedef void (*intHandler_t)(void);
/**
* @brief Initialize Interrupt
*
* Initialize Interrupt by choosing the interrupt type, passing the functionpointer to the handler
* and selecting the priority.
* The interrupt will be automatically enabled and will be able to run after intEnableAll is
* called. If the interrupt should only run at a specific even one can controll it by calling
* intDissable prior to calling intEnableAll and calling intEnbale at a specific point and
* dissabling it again with intDisable
* When the desired interrupt occures the handler will be called.
* The interrupt type and priority level is dependent on the architecture of the target MCU.
* To find more information on what can be done one must read the documentation specific to the
* target MCU.
*
* @param intType interrupt type
* @param handler the interrupthandler
* @param priority the interrupt priority
*/
void intInit(
intrType_t intType,
intHandler_t handler,
uint8_t priority);
/**
* @brief Enable all Interrupts
*
* Enables all interrupts globally.
*
*/
void intEnableAll();
/**
* @brief Disable all Interrups
*
* Dissables all interrupts globally exept the non maskable ones given by the architecture of the
* MCU.
*/
void intDisableAll();
/**
* @brief Enable one interrupt type
*
* The Interrupt for the desired interrupt will be enabled. This means that interrupt of that
* type will occure. To revert this intDisable musst be called.
* It can be called when interrupts are are globally allowed or when disabled.
*
* @param intType interrupt type
*/
void intEnable(
intrType_t intType);
/**
* @brief Dissable one interrupt type
*
* The Interrupt for the desired interrupt will be disabled. This means that no interrupt of that
* type will occure. To revert this intEnable musst be called.
* It can be called when interrupts are are globally allowed or when dissabled.
* It will not stop other all interrupts in contrast to intDissableAll.
*
* @param intType interrupt type
*/
void intDisable(
intrType_t intType);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,190 @@
/**
**************************************************************************************************
* @file pin.h
* @author Kerem Yollu & Edwin Koch
* @date 01.11.2021
* @version 1.0
**************************************************************************************************
* @brief pin functionalities description and implementation template
*
* **Detailed Description :**
*
* This header file for pin control is based on the most common configuation options
* curenty awailable for modern hardware.
* Depending of the used Chip, some function may vary or be unawailable.
* Please take a minute to go and explore the according Chips pin.c file to see woh each function
* is implmented.
*
* @todo
* - 01.11.2021 : Should we add a seprate header in the cls layer containing the pinNo_t ?
* - 01.11.2021 : Depending on request implment a pinLock() function
**************************************************************************************************
*/
#ifndef _GPIO_H_
#define _GPIO_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
// include the target device definitions -> CMAKE chooses the correct file
#include "hardwareDescription.h"
#ifdef RASPBERRY
#endif
/*! Enum of possible Pin Modes */
typedef enum
{
def_mode, /*!< Is the **default** mode */
input, /*!< Set pin as **Input** */
output, /*!< Set pin as **Output** */
analog, /*!< Set pin as **Analog** */
alternate /*!< Set pin as **Alternate** */
}pinMode_t;
/*! Enum of possible Outpout Stages */
typedef enum
{
def_stage, /*!< Set ouput stage to **Default** */
floating, /*!< Set ouput stage to **Floating** */
pushPull, /*!< Set ouput stage to **Push Pull** */
openDrain /*!< Set ouput stage to **Open Drain** */
}pinStage_t;
/*! Enum for the internal Pull-Up/Down resistors */
typedef enum
{
def_res, /*!< **Default** internal resistance */
none, /*!< **Disbales** internal resistance */
pullUp, /*!< Set internal resistance as **Pull-Up** */
pullDown /*!< Set internal resistance as **Pull-Down** */
}pinPullUpDown_t;
/*! Enum to set the pin's speed*/
typedef enum
{
def_speed, /*!< set pin's spped to **Default** */
slow, /*!< set pin's speed to **Slow** */
normal, /*!< set pin's speed to **Normal** */
fast, /*!< set pin's speed to **Fast** */
veryFast /*!< set pin's speed to **Very Fast** */
}pinSpeed_t;
/*! Enum to enable ordisable pin interrupt */
typedef enum
{
disabled, /*!< Interrupt disabled */
enabled /*!< Interrupt enabled */
}pinInterrupt_t;
/*! Pin configuration typedef struct*/
typedef struct
{
pinMode_t md; /*!< Pin mode */
pinStage_t st; /*!< Pin logic state */
pinPullUpDown_t pud; /*!< Pin pullup pulldown status */
pinSpeed_t sp; /*!< Pin busspeed */
pinInterrupt_t intr; /*!< Pin interrupt enable state */
}pinConfiguration_t;
/*! Typedef enum of all possible pin errors */
typedef enum {
notValidMode, /*!< Mode is either not valid orsupported by **Hardwaware** */
UnvalidAlternate, /*!< Alternateive mode is unvalid */
OutOfRangeAlternate, /*!< */
NotValidSpeed, /*!< The choosen bus speed is not supported */
notValidOut, /*!< */
OutOfRange, /*!< */
NotDeclared, /*!< */
NotReachable, /*!< */
NoPullUpDown, /*!< Pull-Up mode is not supported by **HARDWARE"" */
NotAnalog, /*!< Analog mode is not supported by **HARDWARE** */
NotDigital, /*!< Digital mode is not supported by **HARDWARE** */
Blocked, /*!< */
AlreadyUsed, /*!< */
NotGpio /*!< This given pin is not a GPIO **HARDWARE** */
}pinErrors_t;
/**
* @brief Configuration function that will call all the necessary function for an sucessfull pin initialisation
* @param pinNo_t mode_t
* @retval none
*/
void pinConfig(pinNo_t pinNo, pinMode_t mode, pinStage_t stage, pinPullUpDown_t resistance, pinSpeed_t speed);
/**
* @brief Modes to set the direction or function of the pin
*/
void pinSetMode(pinNo_t pinNo, pinMode_t mode);
/**
* @brief Output Stage Push-Pull High-z ect...
*/
void pinSetOutputStage(pinNo_t pinNo, pinStage_t stage);
/**
* @brief Depending of the hardare it is able to select the speed of given pins
*/
void pinSetSpeed(pinNo_t pinNo, pinSpeed_t speed);
/**
* @brief If internal Pull-up or Pull-donws are wailable
*/
void pinSetPullUpDonw(pinNo_t pinNo, pinPullUpDown_t resistance);
/**
* @brief If pin is set as alternate this function will modify the pins functionality
* If pin isn't set as alternate this function will set the pin to alternate mode.
*/
void pinSetAlternate(pinNo_t pinNo, uint16_t alternate);
/**
* @brief Reads the pin's current value
*/
uint8_t pinRead(pinNo_t pinNo);
/**
* @brief Toggles th pin's value
*/
void pinToggle(pinNo_t pinNo);
/**
* @brief Sets the pin hihg or low.
*/
void pinWrite(pinNo_t pinNo, uint8_t state);
/**
* @brief Initiates all the preriferals needed for the given pin
*/
void pinInit(pinNo_t pinNo);
/**
* @brief Deactivates all the preriferals needed for the given pin
*/
void pinDeInit(pinNo_t pinNo);
/**
* @brief Resets pin to default
*/
void pinReset(pinNo_t pinNo);
/**
* @brief Will pirnt tthe rurrent devices pin status and their configrarion.
* Dependeing on the platform an the form of information printing.
*/
void pinHardwareInfo(pinNo_t pinNo);
/**
* @brief Handles the given error and stops all further execution.
* Dependeing on the platfonr an the form of information printing.
*/
void pinThrowError(pinErrors_t error);
#ifdef __cplusplus
}
#endif
#endif // _GPIO_H_

@ -0,0 +1,219 @@
#include "spi.h"
// generic implementation of spi channel class
void spiInitMaster(
spiCH_t spi_hw_ch,
spi_clkPol_t clockPolarity,
spi_phase_t phase,
spi_framef_t frameFormat,
spi_comMode_t comMode,
uint32_t prescaler,
pinNo_t clkPin,
uint16_t altFuncClkPin,
pinNo_t MOSIPin,
uint16_t altFuncMOSIPin,
pinNo_t MISOPin,
uint16_t altFuncMISOPin)
{
// GPIO setup
pinInit(clkPin);
pinInit(MOSIPin);
pinInit(MISOPin);
pinConfig(clkPin, alternate, pushPull, output, veryFast);
pinConfig(MISOPin, alternate, floating, input , veryFast);
pinConfig(MOSIPin, alternate, pushPull, output, veryFast);
pinSetAlternate(clkPin, altFuncClkPin);
pinSetAlternate(MOSIPin, altFuncMOSIPin);
pinSetAlternate(MISOPin, altFuncMISOPin);
// SPI setup
spiEnableBus(spi_hw_ch);
spiSetPolarity(spi_hw_ch,clockPolarity);
spiSetPhase(spi_hw_ch,phase);
spiSetMode(spi_hw_ch, SPI_MASTER);
spiSetClockPrescaler(spi_hw_ch, prescaler);
spiSetFrameFormat(spi_hw_ch,frameFormat);
spiSetSoftwareSlaveManagement(spi_hw_ch,1);
spiSetInternalSlaveSelect(spi_hw_ch,0);
spiSetComMode(spi_hw_ch, comMode);
spiSetClockPrescaler(spi_hw_ch, prescaler);
spiSetBitFrameLength(spi_hw_ch, SPI_FRAME_LENGTH_8BIT);
}
void spiSetupCH(spi_ch_t *ch, spiCH_t spi_hw_ch, pinNo_t chipselectPin)
{
ch->pin = chipselectPin;
ch->spi = spi_hw_ch;
pinWrite(chipselectPin, 0);
}
uint8_t spiReadReg(spi_ch_t *spi_ch, uint8_t reg_address) {
uint8_t buf;
// select target device
pinWrite(spi_ch->pin,0);
// send address of target register
spiTrx8BitPolling(spi_ch->spi, reg_address);
// read from target register
buf = spiTrx8BitPolling(spi_ch->spi,0x00);
// release target device
pinWrite(spi_ch->pin,1);
return buf;
}
void spiAutoReadBlock(spi_ch_t *spi_ch,
uint8_t start_address,
uint8_t* buffer,
uint8_t buf_len) {
uint8_t i = 0;
// select target device
pinWrite(spi_ch->pin,0);
// send address of starting register
spiTrx8BitPolling(spi_ch->spi, start_address);
// read block from device
for(;i < buf_len;i++) {
buffer[i] = spiTrx8BitPolling(spi_ch->spi, 0x00);
}
// release target device
pinWrite(spi_ch->pin,1);
}
void spiWriteReg(spi_ch_t *spi_ch,
uint8_t reg_address,
uint8_t data) {
// select target device
pinWrite(spi_ch->pin,0);
// send address of target register
spiTrx8BitPolling(spi_ch->spi, reg_address);
// write to target register
spiTrx8BitPolling(spi_ch->spi, data);
// release target device
pinWrite(spi_ch->pin,1);
}
void spiWriteBlock(spi_ch_t *spi_ch,
uint8_t start_address,
const uint8_t *data,
uint8_t data_len) {
uint8_t i = 0;
// select target device
pinWrite(spi_ch->pin,0);
// send address of starting register
spiTrx8BitPolling(spi_ch->spi, start_address);
// read block from device
for(;i < data_len;i++) {
spiTrx8BitPolling(spi_ch->spi, data[i]);
}
// release target device
pinWrite(spi_ch->pin,1);
}
void spiWrite8bit(spi_ch_t *spi_ch,
uint8_t bits)
{
pinWrite(spi_ch->pin,0);
spiTrx8BitPolling(spi_ch->spi,bits);
pinWrite(spi_ch->pin,1);
}
uint8_t spiReadWrite8bit(spi_ch_t *spi_ch,
uint8_t bits)
{
uint8_t buf;
pinWrite(spi_ch->pin,0);
buf = spiTrx8BitPolling(spi_ch->spi,bits);
pinWrite(spi_ch->pin,1);
return buf;
}
void spiWrite16bit(spi_ch_t *spi_ch,
uint16_t bits)
{
pinWrite(spi_ch->pin,0);
if(spiGetFrameFormat(spi_ch->spi) == SPI_MSB_FIRST) {
spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 8));
spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits));
} else {
spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits));
spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 8));
}
pinWrite(spi_ch->pin,1);
}
uint16_t spiReadWrite16bit(spi_ch_t *spi_ch,
uint16_t bits)
{
uint16_t buf;
pinWrite(spi_ch->pin,0);
if(spiGetFrameFormat(spi_ch->spi) == SPI_LSB_FIRST) {
buf = spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 8)) << 8;
buf |= spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits));
} else {
buf = spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits));
buf |= spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 8)) << 8;
}
pinWrite(spi_ch->pin,1);
return buf;
}
void spiWrite32bit(spi_ch_t *spi_ch,
uint32_t bits)
{
pinWrite(spi_ch->pin,0);
if(spiGetFrameFormat(spi_ch->spi) == SPI_LSB_FIRST) {
spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 24));
spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 16));
spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 8));
spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits));
} else {
spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits));
spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 8));
spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 16));
spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 24));
}
pinWrite(spi_ch->pin,1);
}
uint32_t spiReadWrite32bit(spi_ch_t *spi_ch,
uint8_t bits)
{
uint32_t buf;
pinWrite(spi_ch->pin,0);
if(spiGetFrameFormat(spi_ch->spi) == SPI_LSB_FIRST) {
buf = spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 24)) << 24;
buf |= spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 16)) << 16;
buf |= spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 8)) << 8;
buf |= spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits));
} else {
buf = spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits));
buf |= spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 8)) >> 8;
buf |= spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 16)) >> 16;
buf |= spiTrx8BitPolling(spi_ch->spi,(uint8_t)(bits >> 24)) >> 24;
}
pinWrite(spi_ch->pin,1);
return buf;
}

@ -0,0 +1,390 @@
/**
**************************************************************************************************
* @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 "hardwareDescription.h"
#include "pin.h"
// TODO: when everything worksmove this into imp.spi.c
//#include "hardwareDescription.h"
//#define SPI_BASE ((SPI_TypeDef *)spiBase_Addr_List[spi_hw_ch])
/*! Enum of possible States*/
typedef enum{
SPI_SLAVE,
SPI_MASTER
} spi_mode_t;
/* Enum of clock polarities*/
typedef enum{
SPI_NONINVERTED,
SPI_INVERTED
}spi_clkPol_t;
/*! Enum of phases*/
typedef enum{
SPI_CAPTURE_ON_FIRST_CLK_TRANSITION,
SPI_CAPTURE_ON_SECCOND_CLK_TRANSITION
} spi_phase_t;
/*! Enum of frame formats*/
typedef enum{
SPI_MSB_FIRST,
SPI_LSB_FIRST
}spi_framef_t;
/*! Enum of frame lenghts*/
typedef enum{
SPI_FRAME_LENGTH_8BIT,
SPI_FRAME_LENGTH_16BIT
}spi_framel_t;
/*! Enum of communication mode*/
typedef enum{
SPI_DOUPLEX,
SPI_SIMPLEX
}spi_comMode_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;
typedef uint8_t (*readReg_t) (uint8_t);
// generic code
/** TODO: setup init with all attributes
* TODO: setup auto pin set alternate function
* @brief This is the spi hardware channel class
* @param spi_hw_ch SPI hardware channel
*/
void spiInitMaster(
spiCH_t spi_hw_ch,
spi_clkPol_t clockPolarity,
spi_phase_t phase,
spi_framef_t frameFormat,
spi_comMode_t comMode,
uint32_t prescaler,
pinNo_t clkPin,
uint16_t altFuncClkPin,
pinNo_t MOSIPin,
uint16_t altFuncMOSIPin,
pinNo_t MISOPin,
uint16_t altFuncMISOPin);
/**
* \brief Set up SPI channel
* Set up a SPI channel by passig a hardware SPI channel and a chipselect pin.
* The chipselect pin will be set to high (chipselect is lowactive).
* \param *ch pointer to SPI channel
* \param spi_hw_ch SPI hardware channel
* \param chipslectPin designated pin for chipslect
*/
void spiSetupCH(
spi_ch_t *ch,
spiCH_t spi_hw_ch,
pinNo_t chipselectPin);
/**
* \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 spiReadReg(
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 spiAutoReadBlock(
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 spiWriteReg(
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 spiWriteBlock(
spi_ch_t *spi_ch,
uint8_t start_address,
const uint8_t *data,
uint8_t data_len);
/**
* \brief write 8 bits
* \param bits 8 bits
*/
void spiWrite8bit(
spi_ch_t *spi_ch,
uint8_t bits);
/**
* \brief read and write simultainously 8 bits
* \param bits 8 bits
* \return 8 bits
*/
uint8_t spiReadWrite8bit(
spi_ch_t *spi_ch,
uint8_t bits);
/**
* \brief write 16 bits
* \param bits 16 bits
*/
void spiWrite16bit(
spi_ch_t *spi_ch,
uint16_t bits);
/**
* \brief read and write simultainously 16 bits
* \param bits 16 bits
* \return 16 bits
*/
uint16_t spiReadWrite16bit(
spi_ch_t *spi_ch,
uint16_t bits);
/**
* \brief write 32 bits
* \param bits 32 bits
*/
void spiWrite32bit(
spi_ch_t *spi_ch,
uint32_t bits);
/**
* \brief read and write simultainously 32 bits
* \param bits 32 bits
* \return 32 bits
*/
uint32_t spiReadWrite32bit(
spi_ch_t *spi_ch,
uint8_t bits);
// implementation
/**
* @brief SPI hardware peripheral reset
* @param spi_hw_ch SPI hardware channel
*/
void spiReset(
spiCH_t spi_hw_ch);
/**
* @brief Enable Bus for SPI
* @param spi_hw_ch SPI hardware channel
*/
void spiEnableBus(
spiCH_t spi_hw_ch);
/**
* @brief Enable SPI hardware channel
* @param spi_hw_ch SPI hardware channel
*/
void spiEnable(
spiCH_t spi_hw_ch);
/**
* @brief Dissable SPI hardware channel
* @param spi_hw_ch SPI hardware channel
*/
void spiDissable(
spiCH_t spi_hw_ch);
/**
* @brief Set SPI operation mode (MASTER or SLAVE)
* @param spi_hw_ch SPI hardware channel
* @param mode
*/
void spiSetMode(
spiCH_t spi_hw_ch,
spi_mode_t mode);
/**
* @brief Set SPI clock polarity
* @param spi_hw_ch SPI hardware channel
* @param clkPol Clock polarity
*/
void spiSetPolarity(
spiCH_t spi_hw_ch,
spi_clkPol_t clkPol);
/**
* @breif Get SPI polarity
* @param spi_hw_ch SPI hardware channel
* @return polarity
*/
spi_clkPol_t spiGetPolarity(
spiCH_t spi_hw_ch);
/**
* @brief Set SPI clock phase
* @param spi_hw_ch SPI hardware channel
* @param phase
*/
void spiSetPhase(
spiCH_t spi_hw_ch,
spi_phase_t phase);
/**
* @brief Get SPI clock phase
* @param spi_hw_ch SPI hardware channel
* @return phase
*/
spi_phase_t spiGetPhase(
spiCH_t spi_hw_ch);
/**
* @brief Set frame length
* one can choose between 4/8/16 bits. For devices that not support a given frame length an error
* will be generated.
* @param spi_hw_ch SPI hardware channel
* @param framel Frame length
*/
void spiSetBitFrameLength(
spiCH_t spi_hw_ch,
spi_framel_t framel);
/**
* @brief Set SPI frame format
* @param spi_hw_ch SPI hardware channel
* @param framef Frame format
*/
void spiSetFrameFormat(
spiCH_t spi_hw_ch,
spi_framef_t framef);
/**
* @brief Get SPI frame format
* @param spi_hw_ch SPI hardware channel
* @return Frame format
*/
spi_framef_t spiGetFrameFormat(
spiCH_t spi_hw_ch);
/**
* @brief Set Clock Prescaler
* This is dependent on your target device. Please enter in the correct value.
* The entered Value will be masked with the maximal number of bits (truncated)
* @param spi_hw_ch SPI hardware channel
* @param clkDiv
*/
void spiSetClockPrescaler(
spiCH_t spi_hw_ch,
uint32_t clkDiv);
/**
* @brief Set communication Mode
* @param spi_hw_ch SPI hardware channel
* @param comMode
*/
void spiSetComMode(
spiCH_t spi_hw_ch,
spi_comMode_t comMode);
/**
* @brief Get Clock Prescaler
* @param spi_hw_ch SPI hardware channel
* @return prescaler
*/
uint32_t spiGetClockPrescaler(
spiCH_t spi_hw_ch);
#if 0
/**
* @brief Set software slave management
* @param logic 1 = enabled, 0 = dissabled
*/
void spiSetSoftwareSlaveManagement(spiCH_t spi_hw_ch, uint8_t logic);
#endif
/**
* @brief Enable software slave management
* @param spi_hw_ch SPI hardware channel
* @param logic Slave management done by software... 1 = enables / 0 = dissabled
*/
void spiSetSoftwareSlaveManagement(
spiCH_t spi_hw_ch,
uint8_t logic);
/**
* @brief Enable internal slave select
* @param spi_hw_ch SPI hardware channel
* @param logic 1 = enable / 0 = dissable
*/
void spiSetInternalSlaveSelect(
spiCH_t spi_hw_ch,
uint8_t logic);
/*!
* @brief Transmits and receives one byte of data in polling mode
* @param spi_hw_ch SPI hardware channel
* @param tx_data 'tx_data' The byte to be transmitted"
* @return The received data
*/
uint8_t spiTrx8BitPolling(
spiCH_t spi_hw_ch,
uint8_t tx_data);
#ifdef __cplusplus
}
#endif
#endif // _SPI_H_

@ -0,0 +1,232 @@
/**
**************************************************************************************************
* @file timer.h
* @author Kerem Yollu & Edwin Koch
* @date 19.12.2021
* @version 1.0
**************************************************************************************************
* @brief This is the genral interface for timers.
*
* **Detailed Description :**
* This the timer interface and belongs to the interface layer
*
* @todo 06.03.22 Following functions are to be implmented : timerSetHz / timerSetMs / timerSetNs / timerSetPs
* @todo 27.03.22 Add Compare capture modules compare/capture/ register set value in function timerInitOutputCompare();
**************************************************************************************************
*/
#ifndef _TIMER_H_
#define _TIMER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "hardwareDescription.h"
#include "pin.h"
/*! Emun of possible Timer Errors */
typedef enum {
functionNotSupported, /*!< This Funtion is not awailable on this **HARDWARE** */
prescalerOutOfRange, /*!< Set prescaler value exeeds the Register's **HARDWARE** size */
ccChannelNoOutOfRange /*!< The Selecter internal Capture/Compare timer cahnnel is not given by the **HARDWARE** size */
} timerError_t;
/*! Enum of possible counting modes */
typedef enum {
upCounting, /*!< Counter is in upcounting mode */
downCounting /*!< Counter is in downcounting mode */
} timerCountDirection_t;
/*! Enum of possible timer modes */
typedef enum {
counter, /*!< Timer is in counting mode */
inputCapture, /*!< */
outputCompare, /*!< */
onePulse /*!< */
} timerMode_t;
/*!
* Output compare modes.
*/
typedef enum {
frozen, /*!< Pin update is **de-activated** even when a compare match happens */
high_on_match, /*!< Pin goes **high** when a compare match occurs */
low_on_match, /*!< Pin goes **low** when a compare match occurs */
toggle, /*!< Pin **toggles** when a compare match occurs */
inactive_force_high, /*!< Pin if forced **high** */
inactive_force_low, /*!< Pin if forced **low** */
pwm_normal, /*!< Standart PWM mode */
pwm_inverted /*!< Inverted PWM mode */
} timerOutputCompareMode_t ;
/*!
* @brief Reset the timer to its default state
* @param timer The handle of the desired timer
*/
void timerReset(timerNo_t timer);
/*!
* @brief Activate the bus on which the desired timer is connected to
* @param timer The handle of the desired timer
*/
void timerActivateBus(timerNo_t timer);
/*!
* @brief Enable the timer
* @param timer The handle of the desired timer
*/
void timerEnable(timerNo_t timer);
/*!
* @brief Disable the timer
* @param timer The handle of the desired timer
*/
void timerDisable(timerNo_t timer);
/*!
* @brief Set the operation mode of the timer
* @param timer The handle of the desired timer
* @param mode The desired operation mode
*/
void timerSetMode(timerNo_t timer, timerMode_t mode);
/*!
* @brief Set the timer conting direction
* @param timer The handle of the desired timer
* @param direction Counting direction
*/
void timerSetCountDirection(timerNo_t timer, timerCountDirection_t direction);
/*!
* @brief Sets the given timer's prescaler value.
*
* This fucntion will also check if the entered prascaler value exeeds the register size.
* If violated the prescalerOutOfRange Error will be generated.
*
* @param timer The handle of the desired timer
* @param prescaler The prescaler value for the timer
*/
void timerSetPrescaler(timerNo_t timer, uint32_t prescaler);
/*!
* @brief Set the postscaler of the timer
*
* This function will throw an error when the postscaler value exceeds the hardware register
* size.
*
* @param timer The handle of the desired timer
* @param postscaler The postscaler value
*/
void timerSetPostscaler(timerNo_t timer, uint32_t postscaler);
/*!
* @brief Set the outoreload value of the timer
* @param timer The handle of the desired timer
* @param reload The reload value
*/
void timerSetAutoReload(timerNo_t timer, uint32_t reload);
uint8_t timerGetUpdateInterrupt(timerNo_t timer);
void timerClearUpdateInterrupt(timerNo_t timer);
void timerClearCounter(timerNo_t timer);
/* Second stage configuration */
/*!
* @brief Initializes the counter of the timer
*
* @param timer The desired timer
* @param prescaler the prescaler value for the counter clock
* @param autoReload The autoreload value for the counter
* @param direction The counter direction
*
*/
void timerInitCounter( timerNo_t timer,
uint32_t prescaler,
uint32_t autoReload,
timerCountDirection_t direction);
/*!
* This funtion is not implemented yet. Will be used to implment pwm functionality of the timer.
*/
void timerInitPwm( timerNo_t timer,
uint32_t prescaler,
uint32_t period,
timerCountDirection_t direction);
/*!
* @brief Sets the Timer to the desired compare mode The function timerInitCounter(); Should be
* called before to init the Timer.
* Calling this function will stop the timer and clear the counter.
*
* @param timer The desired timer number
* @param mode The desired output compare mode
* @param timerIoChannel The internal Timer Capture compare channel to be used.
* @param pinNo The desired Pin Number to be used as outpujt
* @param altFuntion The Alternate funtion No for the given Pin
* @param polarity Sets the the given Pin
* @param ccValue Capture Compare Value
*/
void timerInitOutputCompare( timerNo_t timer,
timerOutputCompareMode_t mode,
uint8_t timerIoChannel,
pinNo_t pinNo,
uint16_t altFunction,
uint8_t polarity,
uint32_t ccValue);
/*!
* @brief Sets the counter compare calue of the desired timer io channel
*
* @param timer The desired timer number
* @param timerIoChannel The internal Timer Capture compare channel to be used.
* @param ccValue Capture Compare Value
*/
void timerSetCounterCompareValue(timerNo_t timer,
uint8_t timerIoChannel,
uint32_t ccValue);
/*!
* @brief Set the outoreload value of the timer
*
* The following calculation is performed.
*
* \f$ f_{timer} = \frac{ BusClock }{ (Prescaler - 1 ) \cdot ( Period - 1 )} \f$
*
* The values of \f$ Period \f$ (Reload Value) and \f$ Prescaler \f$ will be calculated to match
* or come close to the desired timer frequency \f$ f_{timer} \f$.
*
* @param timer The handle of the desired timer
* @param hz The desired frequency in Hz
*/
void timerSetHz(timerNo_t timer, uint16_t hz);
void timerSetMs(timerNo_t timer, uint16_t ms);
void timerSetNs(timerNo_t timer, uint16_t ns);
void timerSetPs(timerNo_t timer, uint16_t ps);
/*!
* @brief Enables the timer
* @param timer The desired timer number
*/
void timerSart(timerNo_t timer);
/*!
* @brief Disables the timer
* @param timer The desired timer number
*/
void timerHalt(timerNo_t timer);
/*!
* @brief Halts the timer and then clears the counter.
* @param timer The desired timer number
*/
void timerStop(timerNo_t timer);
uint32_t timerGetCount(timerNo_t timer);
void timerThrowError(timerError_t error);
#ifdef __cplusplus
}
#endif
#endif // _TIMER_H_

@ -0,0 +1,149 @@
/**
**************************************************************************************************
* @file usart.h
* @author Kerem Yollu & Edwin Koch
* @date 02.11.2021
* @version 1.0
**************************************************************************************************
* @brief USART functionalities description and implementation template
*
* **Detailed Description :**
*
* This header file for pin control is based on the most common configuation options
* curenty awailable for modern hardware.
* Depending of the used Chip, some function may vary or be unawailable.
* Please take a minute to go and explore the according Chips pin.c file to see woh each function
* is implmented.
*
* @todo
* - 03.11.2021 : MAybe find a way to link the awalabe uart channnels with the awailable pins for that USART channel
**************************************************************************************************
*/
#ifndef _USART_H_
#define _USART_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "pin.h"
#define NO_PARITY_CTRL 0
#define PARITY_CTRL 1
/*! Enum of USART Word Lenght Options */
typedef enum
{
seven, /*!< **7 bits** word Lenght */
eight, /*!< **8 bits** word Lenght */
nine /*!< **9 bits** word Lenght */
}usartWordLength_t;
/*! Enum of USART Word Lenght Options */
typedef enum
{
usart1 = USART1_BASE , /*!< USART Channel 1 */
usart2 = USART2_BASE /*!< USART Channel 2 */
}usartNo_t;
/*! Enum of USART Parity Even or Odd */
typedef enum
{
even, /*!< **Even** Parity */
odd /*!< **Odd** Parity */
}usartParity_t;
/*! Enum of USART Hardware flow control options */
typedef enum
{
noFlowControl, /*!< **Disabeled** */
cts, /*!< **CTS** Only */
rts, /*!< **RTS** Only */
ctsRts /*!< **CTS & RTS** Enabled */
}usartHwFlowCtrl_t;
/**
* \brief Enable the USART with the most commment settings
* \param usartNo_t channel Uart **Channel** to be used
* \param pinNo_t pinTx Pin to be used for **Transmit**
* \param pinNo_t pinRx Pin to be used for **Recieve**
* \retval none
*/
void usartInit( usartNo_t channel,
pinNo_t pinTx,
pinNo_t pinRx,
uint32_t baud,
usartWordLength_t lenght,
uint8_t parity,
usartHwFlowCtrl_t flowCtrl);
/**
* \brief Enable the USART Transmission pin, be carefull this function will not link the right pin to the right UART channel.
* \param pinNo_t pinTx Pin to be used for **Transmit**
* \retval none
*/
void usartInitTx(pinNo_t pinTx);
/**
* \brief Enable the USART Recieve pin, be carefull this function will not link the right pin to the right UART channel.
* \param pinNo_t pinRx Pin to be used for **Transmit**
* \retval none
*/
void usartInitRx(pinNo_t pinRx);
/**
* \brief Sets the word lenght of the Usart channel.
* \param usartNo_t channel,
* \param usartWordLength_t lenght
* \retval none
*/
void usartSetWordLenght(usartNo_t channel, usartWordLength_t lenght);
/**
* \brief Sets the Baud Rate of the Usart channel.
* \param usartNo_t channel,
* \param uint32_t baud
* \retval none
*/
void usartSetBaudRate(usartNo_t channel, uint32_t baud);
/**
* \brief Stups Hardware Flow control
* \param usartNo_t channel,
* \param usartHwFlowCtrl_t flowCtrl
* \retval none
*/
void usartSetHwFlowCtrl(usartNo_t channel, usartHwFlowCtrl_t flowCtrl);
/**
* \brief Sends a char array until \0 is detected.
* \param usartNo_t channel,
* \param *ptr pointer to char array
* \retval none
*/
void print_Usart(usartNo_t channel,char *ptr);
/**
* \brief Cheks if the send buffer is empty an than Sends one Char
* \param usartNo_t channel,
* \param uint8_t ch one Character.
* \retval none
*/
void usartSendChar(usartNo_t channel, uint8_t ch);
/**
* \brief Cheks if the recieve buffer is NOT empty an than Rreturns the recieved Char
* \param usartNo_t channel,
* \param uint8_t ch one Character.
* \retval none
*/
uint8_t usartGetChar(usartNo_t channel);
#ifdef __cplusplus
}
#endif
#endif // _USART_H_

@ -30,10 +30,8 @@
extern "C" { extern "C" {
#endif #endif
#include "hardwareDescription.h"
#include "pin.h" #include "pin.h"
#include "hwd_i2c.h"
/*! Enum of possible I2C opperation modes */ /*! Enum of possible I2C opperation modes */
typedef enum{ typedef enum{

@ -21,7 +21,7 @@ extern "C" {
#endif #endif
#include <stdint.h> #include <stdint.h>
#include "hardwareDescription.h" #include "hwd_interrupt.h"
/*! interrupt callback type for the handler */ /*! interrupt callback type for the handler */
typedef void (*intHandler_t)(void); typedef void (*intHandler_t)(void);

@ -30,7 +30,7 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
// include the target device definitions -> CMAKE chooses the correct file // include the target device definitions -> CMAKE chooses the correct file
#include "hardwareDescription.h" #include "hwd_pin.h"
#ifdef RASPBERRY #ifdef RASPBERRY
#endif #endif

@ -20,7 +20,7 @@
extern "C" { extern "C" {
#endif #endif
#include "hardwareDescription.h" #include "hwd_spi.h"
#include "pin.h" #include "pin.h"
// TODO: when everything worksmove this into imp.spi.c // TODO: when everything worksmove this into imp.spi.c

@ -22,7 +22,7 @@
extern "C" { extern "C" {
#endif #endif
#include "hardwareDescription.h" #include "hwd_timer.h"
#include "pin.h" #include "pin.h"
/*! Emun of possible Timer Errors */ /*! Emun of possible Timer Errors */

@ -26,7 +26,7 @@
extern "C" { extern "C" {
#endif #endif
#include "hwd_usart.h"
#include "pin.h" #include "pin.h"
#define NO_PARITY_CTRL 0 #define NO_PARITY_CTRL 0

@ -87,6 +87,22 @@ build()
echo "+--------------------------------------+" echo "+--------------------------------------+"
echo -e "\e[32m" echo -e "\e[32m"
fi fi
if [ "$CSL_TO_USE" == "stm32f042k6t6" ];then
echo -e "\e[36m"
echo "+--------------------------------------+"
echo -e "\tFlashing $CSL_TO_USE"
echo "+--------------------------------------+"
echo -e "\e[32m"
sudo st-flash write $CSL_TO_USE.bin 0x08000000
echo -e "\e[36m"
echo "+--------------------------------------+"
echo -e "\tFlashing has Finished"
echo "+--------------------------------------+"
echo -e "\e[32m"
fi
fi fi
} }

Loading…
Cancel
Save