Init of project with the various libraries.
This commit is contained in:
commit
a84307a4b3
13 changed files with 975 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
.obsidian
|
0
README.md
Normal file
0
README.md
Normal file
27
driver-algu/inc/gpio.h
Normal file
27
driver-algu/inc/gpio.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef MYGPIO_H
|
||||||
|
#define MYGPIO_H
|
||||||
|
#include "stm32f10x.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GPIO_TypeDef * GPIO;
|
||||||
|
char GPIO_Pin; //numero de 0 a 15
|
||||||
|
char GPIO_Conf; //voir ci dessous
|
||||||
|
} MyGPIO_Struct_TypeDef;
|
||||||
|
|
||||||
|
#define In_Floating 0x4
|
||||||
|
#define In_PullDown 0x7 //faire
|
||||||
|
#define In_PullUp 0x8 //faire
|
||||||
|
#define In_Analog 0x0
|
||||||
|
#define Out_Ppull 0x2
|
||||||
|
#define Out_OD 0x6
|
||||||
|
#define AltOut_Ppull 0xA
|
||||||
|
#define AltOut_OD 0xE
|
||||||
|
|
||||||
|
void MyGPIO_InitClock(void);
|
||||||
|
void MyGPIO_Init(MyGPIO_Struct_TypeDef * GPIOStructPtr);
|
||||||
|
int MyGPIO_Read(GPIO_TypeDef * GPIO, char GPIO_Pin);
|
||||||
|
void MyGPIO_Set(GPIO_TypeDef * GPIO, char GPIO_Pin);
|
||||||
|
void MyGPIO_Reset(GPIO_TypeDef * GPIO, char GPIO_Pin);
|
||||||
|
void MyGPIO_Toggle(GPIO_TypeDef * GPIO, char GPIO_Pin);
|
||||||
|
|
||||||
|
#endif
|
19
driver-algu/inc/timer.h
Normal file
19
driver-algu/inc/timer.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef MYTIMER_H
|
||||||
|
#define MYTIMER_H
|
||||||
|
#include "stm32f10x.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
TIM_TypeDef * Timer;
|
||||||
|
unsigned short ARR;
|
||||||
|
unsigned short PSC;
|
||||||
|
} MyTimer_Struct_Typedef;
|
||||||
|
|
||||||
|
void MyTimer_Base_Init(MyTimer_Struct_Typedef * Timer);
|
||||||
|
void MyTimer_ActiveIT(TIM_TypeDef * Timer, char Prio, void (*IT_function) (void));
|
||||||
|
void MyTimer_PWM(TIM_TypeDef * Timer ,char Channel);
|
||||||
|
void MyTimer_DutyCycle(TIM_TypeDef * Timer, char Channel, unsigned char DutyCycle);
|
||||||
|
|
||||||
|
#define MyTimer_Base_Start(Tim) (Tim.Timer->CR1 |= TIM_CR1_CEN)
|
||||||
|
#define MyTimer_Base_Stop(Tim) (Tim.Timer->CR1 &= ~TIM_CR1_CEN)
|
||||||
|
|
||||||
|
#endif
|
79
driver-algu/src/gpio.c
Normal file
79
driver-algu/src/gpio.c
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
void MyGPIO_InitClock(void) {
|
||||||
|
RCC->APB2ENR |= (0x01 << 2) | (0x01 << 3) | (0x01 << 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyGPIO_Init(MyGPIO_Struct_TypeDef * GPIOStructPtr) {
|
||||||
|
if (GPIOStructPtr->GPIO_Pin >= 8) {
|
||||||
|
switch (GPIOStructPtr->GPIO_Conf) {
|
||||||
|
case In_PullDown:
|
||||||
|
GPIOStructPtr->GPIO->CRH &= ~(0xF << (4 * (GPIOStructPtr->GPIO_Pin % 8)));
|
||||||
|
GPIOStructPtr->GPIO->CRH |= (0x8 << (4 * (GPIOStructPtr->GPIO_Pin % 8)));
|
||||||
|
GPIOStructPtr->GPIO->ODR &= (0x0 << GPIOStructPtr->GPIO_Pin);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case In_PullUp:
|
||||||
|
GPIOStructPtr->GPIO->CRH &= ~(0xF << (4 * (GPIOStructPtr->GPIO_Pin % 8)));
|
||||||
|
GPIOStructPtr->GPIO->CRH |= (0x8 << (4 * (GPIOStructPtr->GPIO_Pin % 8)));
|
||||||
|
GPIOStructPtr->GPIO->ODR |= (0x1 << GPIOStructPtr->GPIO_Pin);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case In_Floating:
|
||||||
|
case In_Analog:
|
||||||
|
case Out_Ppull:
|
||||||
|
case Out_OD:
|
||||||
|
case AltOut_Ppull:
|
||||||
|
case AltOut_OD:
|
||||||
|
GPIOStructPtr->GPIO->CRH &= ~(0xF << (4 * (GPIOStructPtr->GPIO_Pin % 8)));
|
||||||
|
GPIOStructPtr->GPIO->CRH |= (GPIOStructPtr->GPIO_Conf << (4 * (GPIOStructPtr->GPIO_Pin % 8)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (GPIOStructPtr->GPIO_Conf) {
|
||||||
|
case In_PullDown:
|
||||||
|
GPIOStructPtr->GPIO->CRH &= ~(0xF << (4 * (GPIOStructPtr->GPIO_Pin)));
|
||||||
|
GPIOStructPtr->GPIO->CRH |= (0x8 << (4 * (GPIOStructPtr->GPIO_Pin)));
|
||||||
|
GPIOStructPtr->GPIO->ODR &= (0x0 << GPIOStructPtr->GPIO_Pin);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case In_PullUp:
|
||||||
|
GPIOStructPtr->GPIO->CRL &= ~(0xF << (4 * (GPIOStructPtr->GPIO_Pin)));
|
||||||
|
GPIOStructPtr->GPIO->CRL |= (0x8 << (4 * (GPIOStructPtr->GPIO_Pin)));
|
||||||
|
GPIOStructPtr->GPIO->ODR |= (0x1 << GPIOStructPtr->GPIO_Pin);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case In_Floating:
|
||||||
|
case In_Analog:
|
||||||
|
case Out_Ppull:
|
||||||
|
case Out_OD:
|
||||||
|
case AltOut_Ppull:
|
||||||
|
case AltOut_OD:
|
||||||
|
GPIOStructPtr->GPIO->CRL &= ~(0xF << (4 * (GPIOStructPtr->GPIO_Pin)));
|
||||||
|
GPIOStructPtr->GPIO->CRL |= (GPIOStructPtr->GPIO_Conf << (4 * (GPIOStructPtr->GPIO_Pin)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int MyGPIO_Read(GPIO_TypeDef * GPIO, char GPIO_Pin) {
|
||||||
|
return ((GPIO->IDR & (0x1 << GPIO_Pin)) >> GPIO_Pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyGPIO_Set(GPIO_TypeDef * GPIO, char GPIO_Pin) {
|
||||||
|
GPIO->ODR |= (0x1 << GPIO_Pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyGPIO_Reset(GPIO_TypeDef * GPIO, char GPIO_Pin) {
|
||||||
|
GPIO->ODR &= (0x0 << GPIO_Pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyGPIO_Toggle(GPIO_TypeDef * GPIO, char GPIO_Pin) {
|
||||||
|
if (MyGPIO_Read(GPIO, GPIO_Pin) == 0x1) {
|
||||||
|
MyGPIO_Reset(GPIO, GPIO_Pin);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MyGPIO_Set(GPIO, GPIO_Pin);
|
||||||
|
}
|
||||||
|
}
|
192
driver-algu/src/timer.c
Normal file
192
driver-algu/src/timer.c
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
#include "timer.h"
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
void plantage(void) {
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
void (*IT_Tim1) (void) = plantage;
|
||||||
|
void (*IT_Tim2) (void) = plantage;
|
||||||
|
void (*IT_Tim3) (void) = plantage;
|
||||||
|
void (*IT_Tim4) (void) = plantage;
|
||||||
|
|
||||||
|
void MyTimer_Base_Init(MyTimer_Struct_Typedef * Timer) {
|
||||||
|
if ((Timer->Timer) == TIM1)
|
||||||
|
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
||||||
|
if ((Timer->Timer) == TIM2)
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
|
||||||
|
if ((Timer->Timer) == TIM3)
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||||
|
if ((Timer->Timer) == TIM4)
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
|
||||||
|
|
||||||
|
Timer->Timer->PSC = Timer->PSC;
|
||||||
|
Timer->Timer->ARR = Timer->ARR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyTimer_ActiveIT(TIM_TypeDef * Timer, char Prio, void (*IT_function) (void)) {
|
||||||
|
Timer->DIER |= TIM_DIER_UIE;
|
||||||
|
if (Timer == TIM2) {
|
||||||
|
NVIC_EnableIRQ(TIM1_BRK_IRQn);
|
||||||
|
NVIC_SetPriority(TIM1_BRK_IRQn, Prio);
|
||||||
|
IT_Tim1 = IT_function;
|
||||||
|
}
|
||||||
|
if (Timer == TIM2) {
|
||||||
|
NVIC_EnableIRQ(TIM2_IRQn);
|
||||||
|
NVIC_SetPriority(TIM2_IRQn, Prio);
|
||||||
|
IT_Tim2 = IT_function;
|
||||||
|
}
|
||||||
|
if (Timer == TIM3) {
|
||||||
|
NVIC_EnableIRQ(TIM3_IRQn);
|
||||||
|
NVIC_SetPriority(TIM3_IRQn, Prio);
|
||||||
|
IT_Tim3 = IT_function;
|
||||||
|
}
|
||||||
|
if (Timer == TIM4) {
|
||||||
|
NVIC_EnableIRQ(TIM4_IRQn);
|
||||||
|
NVIC_SetPriority(TIM4_IRQn, Prio);
|
||||||
|
IT_Tim4 = IT_function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIM1_IRQHandler(void) {
|
||||||
|
TIM1->SR &= ~TIM_SR_UIF;
|
||||||
|
(*IT_Tim1)();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIM2_IRQHandler(void) {
|
||||||
|
TIM2->SR &= ~TIM_SR_UIF;
|
||||||
|
(*IT_Tim2)();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIM3_IRQHandler(void) {
|
||||||
|
TIM3->SR &= ~TIM_SR_UIF;
|
||||||
|
(*IT_Tim3)();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIM4_IRQHandler(void) {
|
||||||
|
TIM4->SR &= ~TIM_SR_UIF;
|
||||||
|
(*IT_Tim4)();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyTimer_PWM(TIM_TypeDef * Timer ,char Channel)
|
||||||
|
{
|
||||||
|
MyGPIO_Struct_TypeDef PWM_OUT;
|
||||||
|
PWM_OUT.GPIO_Conf = AltOut_Ppull;
|
||||||
|
switch (Channel) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
Timer->CCMR1 &= ~TIM_CCMR1_OC1M_0;
|
||||||
|
Timer->CCMR1 |= (TIM_CCMR1_OC1M_1| TIM_CCMR1_OC1M_2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
Timer->CCMR2 &= ~TIM_CCMR1_OC1M_0;
|
||||||
|
Timer->CCMR2 |= (TIM_CCMR1_OC1M_1| TIM_CCMR1_OC1M_2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer->CCER |= (TIM_CCER_CC1E << (4*(Channel-1)));
|
||||||
|
|
||||||
|
if(Timer == TIM1)
|
||||||
|
{
|
||||||
|
TIM1->BDTR |= 0x8000;
|
||||||
|
PWM_OUT.GPIO = GPIOA;
|
||||||
|
switch (Channel) {
|
||||||
|
case 1:
|
||||||
|
PWM_OUT.GPIO_Pin = 8;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
PWM_OUT.GPIO_Pin = 9;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
PWM_OUT.GPIO_Pin = 10;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
PWM_OUT.GPIO_Pin = 11;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(Timer == TIM2)
|
||||||
|
{
|
||||||
|
PWM_OUT.GPIO = GPIOA;
|
||||||
|
switch (Channel) {
|
||||||
|
case 1:
|
||||||
|
PWM_OUT.GPIO_Pin = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
PWM_OUT.GPIO_Pin = 1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
PWM_OUT.GPIO_Pin = 2;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
PWM_OUT.GPIO_Pin = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Timer == TIM3)
|
||||||
|
{
|
||||||
|
switch (Channel) {
|
||||||
|
case 1:
|
||||||
|
PWM_OUT.GPIO = GPIOA;
|
||||||
|
PWM_OUT.GPIO_Pin = 6;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
PWM_OUT.GPIO = GPIOA;
|
||||||
|
PWM_OUT.GPIO_Pin = 7;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
PWM_OUT.GPIO = GPIOB;
|
||||||
|
PWM_OUT.GPIO_Pin = 0;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
PWM_OUT.GPIO = GPIOB;
|
||||||
|
PWM_OUT.GPIO_Pin = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Timer == TIM4)
|
||||||
|
{
|
||||||
|
PWM_OUT.GPIO = GPIOB;
|
||||||
|
switch (Channel) {
|
||||||
|
case 1:
|
||||||
|
PWM_OUT.GPIO_Pin = 6;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
PWM_OUT.GPIO_Pin = 7;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
PWM_OUT.GPIO_Pin = 8;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
PWM_OUT.GPIO_Pin = 9;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyGPIO_Init(&PWM_OUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyTimer_DutyCycle(TIM_TypeDef * Timer, char Channel, unsigned char DutyCycle)
|
||||||
|
{
|
||||||
|
unsigned int RC;
|
||||||
|
RC = ((Timer->ARR)/100)*(DutyCycle);
|
||||||
|
switch (Channel) {
|
||||||
|
case 1:
|
||||||
|
Timer->CCR1 = RC;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
Timer->CCR2 = RC;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
Timer->CCR3 = RC;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
Timer->CCR4 = RC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
70
driver-siyo/gpiodriver.c
Normal file
70
driver-siyo/gpiodriver.c
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
#include "gpiodriver.h"
|
||||||
|
|
||||||
|
void MyGPIO_Init(MyGPIO_Struct_TypeDef * GPIOStructPtr)
|
||||||
|
{
|
||||||
|
RCC->APB2ENR |= GPIO2Int(GPIOStructPtr->GPIO);
|
||||||
|
//We get the pointer of the CRH/CRL depending on the IO_Pin number
|
||||||
|
volatile uint32_t * CRAny = GPIOStructPtr->GPIO_Pin >= 0x08 ? &(GPIOStructPtr->GPIO->CRH):&(GPIOStructPtr->GPIO->CRL);
|
||||||
|
//setup high or low
|
||||||
|
*CRAny &= ~(0xF << (GPIOStructPtr->GPIO_Pin%8)*4); //reset
|
||||||
|
//for input pull or push
|
||||||
|
switch(GPIOStructPtr->GPIO_Conf)
|
||||||
|
{
|
||||||
|
case In_PullUp:
|
||||||
|
GPIOStructPtr->GPIO->ODR |= (0x01 << GPIOStructPtr->GPIO_Pin); //if pullup -> ODR = 1
|
||||||
|
*CRAny |= (In_PullDown << (GPIOStructPtr->GPIO_Pin%8)*4); //set pin mode -> force to In_PullDown because PullDown is modified
|
||||||
|
break;
|
||||||
|
case In_PullDown:
|
||||||
|
GPIOStructPtr->GPIO->ODR &= ~(0x01 << GPIOStructPtr->GPIO_Pin); //if pullup -> ODR = 0
|
||||||
|
default:
|
||||||
|
*CRAny |= (GPIOStructPtr->GPIO_Conf << (GPIOStructPtr->GPIO_Pin%8)*4); //set pin mode for any input/output
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int MyGPIO_Read(GPIO_TypeDef * GPIO, uint8_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
return (GPIO->IDR & (0x1 << GPIO_Pin)) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyGPIO_Set(GPIO_TypeDef * GPIO, uint8_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
GPIO->BSRR = (1 << GPIO_Pin); //BSX set register
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyGPIO_Reset(GPIO_TypeDef * GPIO, uint8_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
GPIO->BRR = (1 << GPIO_Pin); //BRX = BSX+16 reset register
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyGPIO_Toggle(GPIO_TypeDef * GPIO, uint8_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
if((GPIO->ODR = GPIO->ODR & (1 << GPIO_Pin)) > 0)
|
||||||
|
{
|
||||||
|
GPIO->BRR = (1 << GPIO_Pin); //reset
|
||||||
|
} else {
|
||||||
|
GPIO->BSRR = (1 << GPIO_Pin); //set
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int GPIO2Int(GPIO_TypeDef * GPIOX)
|
||||||
|
{
|
||||||
|
if(GPIOX == GPIOA)
|
||||||
|
{
|
||||||
|
return (0x01 << 2);
|
||||||
|
} else if (GPIOX == GPIOB){
|
||||||
|
return (0x01 << 3);
|
||||||
|
} else if (GPIOX == GPIOC){
|
||||||
|
return (0x01 << 4);
|
||||||
|
} else if (GPIOX == GPIOD){
|
||||||
|
return (0x01 << 5);
|
||||||
|
} else if (GPIOX == GPIOE){
|
||||||
|
return (0x01 << 6);
|
||||||
|
} else if (GPIOX == GPIOF){
|
||||||
|
return (0x01 << 7);
|
||||||
|
} else if (GPIOX == GPIOE){
|
||||||
|
return (0x01 << 8);
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
}
|
28
driver-siyo/gpiodriver.h
Normal file
28
driver-siyo/gpiodriver.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef GPIODRIVER_H
|
||||||
|
#define GPIODRIVER_H
|
||||||
|
#include "stm32f10x.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GPIO_TypeDef * GPIO; //GPIO A,B,C,D...
|
||||||
|
uint8_t GPIO_Pin; //numero de 0 à 15
|
||||||
|
uint8_t GPIO_Conf; //voir ci dessous
|
||||||
|
} MyGPIO_Struct_TypeDef;
|
||||||
|
|
||||||
|
#define In_Floating 0x04
|
||||||
|
#define In_PullDown 0x08
|
||||||
|
#define In_PullUp 0xF8
|
||||||
|
#define In_Analog 0x00
|
||||||
|
#define Out_PullUp 0x01
|
||||||
|
#define Out_OD 0x05
|
||||||
|
#define AltOut_Ppull 0x09
|
||||||
|
#define AltOut_OD 0x0d
|
||||||
|
|
||||||
|
int GPIO2Int(GPIO_TypeDef * GPIOX);
|
||||||
|
void MyGPIO_Init(MyGPIO_Struct_TypeDef * GPIOStructPtr);
|
||||||
|
int MyGPIO_Read(GPIO_TypeDef * GPIO, uint8_t GPIO_Pin);
|
||||||
|
void MyGPIO_Set(GPIO_TypeDef * GPIO, uint8_t GPIO_Pin);
|
||||||
|
void MyGPIO_Reset(GPIO_TypeDef * GPIO, uint8_t GPIO_Pin);
|
||||||
|
void MyGPIO_Toggle(GPIO_TypeDef * GPIO, uint8_t GPIO_Pin);
|
||||||
|
|
||||||
|
#endif
|
162
driver-siyo/timerdriver.c
Normal file
162
driver-siyo/timerdriver.c
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
#include "timerdriver.h"
|
||||||
|
|
||||||
|
void (* pFnc) (void); /* déclaration d’un pointeur de fonction */
|
||||||
|
|
||||||
|
void Init_Periph (void (* ptrFonction)(void))
|
||||||
|
{
|
||||||
|
pFnc = ptrFonction; /* affectation du pointeur */
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyTimer_Base_Init(MyTimer_Struct_TypeDef * Timer)
|
||||||
|
{
|
||||||
|
//TIM1 uses the APB2ENR register from RCC. The others uses the APB1ENR, so we check this value.
|
||||||
|
if(Timer->Timer == TIM1)
|
||||||
|
{
|
||||||
|
RCC->APB2ENR |= TimerX2Int(Timer->Timer);
|
||||||
|
} else {
|
||||||
|
RCC->APB1ENR |= TimerX2Int(Timer->Timer);
|
||||||
|
}
|
||||||
|
Timer->Timer->ARR = Timer->ARR;
|
||||||
|
Timer->Timer->PSC = Timer->PSC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyTimer_ActiveIT(TIM_TypeDef * TimerX, uint8_t Prio)
|
||||||
|
{
|
||||||
|
uint8_t positionTimerIT = TimerIT2UInt(TimerX);
|
||||||
|
TimerX->DIER |= (0x1<<UIE);
|
||||||
|
NVIC->IP[positionTimerIT] |= (Prio << 0x4);
|
||||||
|
NVIC->ISER[0] |= (0x1<<positionTimerIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyTimer_PWM_Init(MyPWM_Struct_TypeDef * PWM)
|
||||||
|
{
|
||||||
|
switch(PWM->channel)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
PWM->Timer->CCMR1 |= (PWMMode_1<<OC24M_START); //We activate the PWM Mode 1 for the given channel
|
||||||
|
PWM->Timer->CCR2 = PWM->CCR; //Compare Capture register count
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
PWM->Timer->CCMR2 |= (PWMMode_1<<OC13M_START);
|
||||||
|
PWM->Timer->CCR3 = PWM->CCR;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
PWM->Timer->CCMR2 |= (PWMMode_1<<OC24M_START);
|
||||||
|
PWM->Timer->CCR4 = PWM->CCR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PWM->Timer->CCMR1 |= (PWMMode_1<<OC13M_START);
|
||||||
|
PWM->Timer->CCR1 = PWM->CCR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
PWM->Timer->CCER |= (1<<4*(PWM->channel-1)); //enable capture/compare registers
|
||||||
|
}
|
||||||
|
|
||||||
|
MyGPIO_Struct_TypeDef GPIOFromPWM(MyPWM_Struct_TypeDef PWM)
|
||||||
|
{
|
||||||
|
//use of C99 compound literal for return statement, may not work on C90.
|
||||||
|
if(PWM.Timer == TIM2)
|
||||||
|
{
|
||||||
|
//PA0 -> TIM2,CH1... iteration
|
||||||
|
return (MyGPIO_Struct_TypeDef){GPIOA,PWM.channel-1,AltOut_Ppull};
|
||||||
|
}
|
||||||
|
else if(PWM.Timer == TIM3)
|
||||||
|
{
|
||||||
|
if(PWM.channel > 2) {
|
||||||
|
return (MyGPIO_Struct_TypeDef){GPIOB,PWM.channel-3,AltOut_Ppull}; //PB0 -> TIM3,CH3;PB1 -> TIM3,CH4
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (MyGPIO_Struct_TypeDef){GPIOA,PWM.channel+5,AltOut_Ppull}; //PA6 -> TIM3,CH1;PA7 -> TIM3,CH2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(PWM.Timer == TIM4)
|
||||||
|
{
|
||||||
|
return (MyGPIO_Struct_TypeDef){GPIOB,PWM.channel+5,AltOut_Ppull}; //PB6 -> TIM4,CH1... iteration
|
||||||
|
}
|
||||||
|
else { //TIM1 case
|
||||||
|
return (MyGPIO_Struct_TypeDef){GPIOA,PWM.channel+7,AltOut_Ppull};//PA8 -> TIM1,CH1... iteration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int TimerX2Int(TIM_TypeDef * TimerX)
|
||||||
|
{
|
||||||
|
if(TimerX == TIM1)
|
||||||
|
{
|
||||||
|
return (0x01 << 11);
|
||||||
|
} else if (TimerX == TIM2){
|
||||||
|
return (0x01 << 0);
|
||||||
|
} else if (TimerX == TIM3){
|
||||||
|
return (0x01 << 1);
|
||||||
|
} else if (TimerX == TIM4){
|
||||||
|
return (0x01 << 2);
|
||||||
|
} /*else if (TimerX == TIM5){
|
||||||
|
return (0x01 << 3);
|
||||||
|
} else if (TimerX == TIM6){
|
||||||
|
return (0x01 << 4);
|
||||||
|
} else if (TimerX == TIM7){
|
||||||
|
return (0x01 << 5);
|
||||||
|
} else if (TimerX == TIM8){
|
||||||
|
return (0x01 << 13);
|
||||||
|
} else if (TimerX == TIM9){ //For now we dont do timer > 4
|
||||||
|
return (0x01 << 19);
|
||||||
|
} else if (TimerX == TIM10){
|
||||||
|
return (0x01 << 20);
|
||||||
|
} else if (TimerX == TIM11){
|
||||||
|
return (0x01 << 21);
|
||||||
|
} else if (TimerX == TIM12){
|
||||||
|
return (0x01 << 6);
|
||||||
|
} else if (TimerX == TIM13){
|
||||||
|
return (0x01 << 7);
|
||||||
|
} else if (TimerX == TIM14){
|
||||||
|
return (0x01 << 8);
|
||||||
|
}*/ else {
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t TimerIT2UInt(TIM_TypeDef * TimerX)
|
||||||
|
{
|
||||||
|
if(TimerX == TIM1)
|
||||||
|
{
|
||||||
|
return TIM1_CC_IRQn;
|
||||||
|
} else if(TimerX == TIM2)
|
||||||
|
{
|
||||||
|
return TIM2_IRQn;
|
||||||
|
} else if(TimerX == TIM3)
|
||||||
|
{
|
||||||
|
return TIM3_IRQn;
|
||||||
|
} else if(TimerX == TIM4)
|
||||||
|
{
|
||||||
|
return 30;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIM1_CC_IRQHandler(void)
|
||||||
|
{
|
||||||
|
if (pFnc != 0)
|
||||||
|
(*pFnc) (); /* appel indirect de la fonction */
|
||||||
|
TIM1->SR &= ~(0x1<<UIF);//reset flag
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIM2_IRQHandler(void)
|
||||||
|
{
|
||||||
|
if (pFnc != 0)
|
||||||
|
(*pFnc) (); /* appel indirect de la fonction */
|
||||||
|
TIM2->SR &= ~(0x1<<UIF);//reset flag
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIM3_IRQHandler(void)
|
||||||
|
{
|
||||||
|
if (pFnc != 0)
|
||||||
|
(*pFnc) (); /* appel indirect de la fonction */
|
||||||
|
TIM3->SR &= ~(0x1<<UIF);//reset flag
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIM4_IRQHandler(void)
|
||||||
|
{
|
||||||
|
if (pFnc != 0)
|
||||||
|
(*pFnc) (); /* appel indirect de la fonction */
|
||||||
|
TIM4->SR &= ~(0x1<<UIF);//reset flag
|
||||||
|
}
|
39
driver-siyo/timerdriver.h
Normal file
39
driver-siyo/timerdriver.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef TIMERDRIVER_H
|
||||||
|
#define TIMERDRIVER_H
|
||||||
|
#include "stm32f10x.h"
|
||||||
|
#include "gpiodriver.h"
|
||||||
|
|
||||||
|
#define CEN 0x0
|
||||||
|
#define UIE 0x0
|
||||||
|
#define UIF 0x0
|
||||||
|
#define MOE 0xF
|
||||||
|
#define OC13M_START 0x4
|
||||||
|
#define OC24M_START 0xC
|
||||||
|
#define PWMMode_1 0x6
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
TIM_TypeDef * Timer; //TIM1 -> TIM4
|
||||||
|
unsigned short ARR;
|
||||||
|
unsigned short PSC;
|
||||||
|
} MyTimer_Struct_TypeDef;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
TIM_TypeDef * Timer; //TIM1 -> TIM4
|
||||||
|
uint8_t channel;
|
||||||
|
uint16_t CCR;
|
||||||
|
} MyPWM_Struct_TypeDef;
|
||||||
|
|
||||||
|
void MyTimer_Base_Init(MyTimer_Struct_TypeDef * Timer);
|
||||||
|
int TimerX2Int(TIM_TypeDef * TimerX);
|
||||||
|
uint8_t TimerIT2UInt(TIM_TypeDef * TimerX);
|
||||||
|
void MyTimer_ActiveIT(TIM_TypeDef * TimerX, uint8_t Prio);
|
||||||
|
void Init_Periph (void (* ptrFonction)(void));
|
||||||
|
void MyTimer_PWM_Init(MyPWM_Struct_TypeDef * PWM);
|
||||||
|
MyGPIO_Struct_TypeDef GPIOFromPWM(MyPWM_Struct_TypeDef PWM);
|
||||||
|
|
||||||
|
#define MyTimer_Base_Start(Timer) (Timer->CR1 |= (0x01<<CEN))
|
||||||
|
#define MyTimer_Base_Stop(Timer) (Timer->CR1 &= ~(0x01<<CEN))
|
||||||
|
#define MyPWM_Base_Start(Timer) (Timer->BDTR |= (1<<MOE)) //Main output enable
|
||||||
|
#define MyPWM_Base_Stop(Timer) (Timer->BDTR &= ~(1<<MOE)) //Main output enable
|
||||||
|
|
||||||
|
#endif
|
BIN
driver/Lib_Com_Periph_2022.lib
Normal file
BIN
driver/Lib_Com_Periph_2022.lib
Normal file
Binary file not shown.
229
driver/MyI2C.h
Normal file
229
driver/MyI2C.h
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
#ifndef _I2C_
|
||||||
|
#define _I2C_
|
||||||
|
|
||||||
|
#include "stm32f10x.h"
|
||||||
|
|
||||||
|
/*************************************************************************************
|
||||||
|
===================== By Periph team INSA GEI 2022 ===========================
|
||||||
|
*************************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*************************************************************************************
|
||||||
|
===================== I2C les IO STM32F103 =================================
|
||||||
|
*************************************************************************************
|
||||||
|
|
||||||
|
Les IO sont pris en charge par la lib, pas besoin de faire les configurations Alt OD.
|
||||||
|
|
||||||
|
**I2C1**
|
||||||
|
SCL PB6
|
||||||
|
SDA PB7
|
||||||
|
|
||||||
|
**I2C2**
|
||||||
|
SCL PB10
|
||||||
|
SDA PB11
|
||||||
|
|
||||||
|
|
||||||
|
*************************************************************************************
|
||||||
|
==================== Fondamentaux I2C ==========================================
|
||||||
|
*************************************************************************************
|
||||||
|
- Bus synchrone Low speed (<100kHz) ou high speed (=400kHz), Ici Low speed 100kHz.
|
||||||
|
- Transfert octet par octet, poids fort en premier, avec aquittement pour chaque octet
|
||||||
|
- Deux lignes SDA et SCL (horloge) en open drain, repos '1'
|
||||||
|
- bit "normal" = SDA stable lors du pulse SCL (ie durant l'état haut de SCL, SDA est stable)
|
||||||
|
- bit Start/Stop/Restart = SDA non stable lorsque SCL vaut '1' (violation règle précédente)
|
||||||
|
* Start : front descendant de SDA lorsque SCL vaut '1'
|
||||||
|
* Stop : front montant de SDA lorsque SCL = '1'
|
||||||
|
* Restart = Start en cours de trame (typiquement pour changer Write/read).
|
||||||
|
- uC en Mode Master uniquement (c'est notre choix) : c'est le uC qui est maître de l'horloge SCL.
|
||||||
|
- Le Slave a une @ 7 bits. On ajoute un bit LSB qui est /WR (donc 0 pour écriture, 1 pour lecture)
|
||||||
|
- Une adresse s'écrit donc |a6 a5 a4 a3 a2 a1 a0 /WR| ce qui donne 8 bits. Elle indique une future
|
||||||
|
lecture ou écriture.
|
||||||
|
On parle d'@ 7 bits en regroupant |a6 a5 a4 a3 a2 a1 a0|
|
||||||
|
On parle d'@ 8 bits en regroupant |a6 a5 a4 a3 a2 a1 a0 /WR| (donc une @ écriture, une @ lecture)
|
||||||
|
NB : préférer le concept @7bits...c'est plus clair.
|
||||||
|
|
||||||
|
- On peut lire ou écrire une ou plusieurs données à la suite. C'est lors de l'envoie de l'adresse Slave
|
||||||
|
par le Master que le sens à venir pour les datas est indiqué.
|
||||||
|
- En écriture,
|
||||||
|
* les Ack sont faits par le slave après chaque octet envoyé par le master (Ack = mise à 0 le bit 9).
|
||||||
|
- En lecture,
|
||||||
|
* dès que le l@ slave est transmise (/RW = 1), et le Ack réalisé, le slave positionne le bit 7
|
||||||
|
du prochain octet à lire sur SDA par anticipation ,
|
||||||
|
* le master enchaîne ses pulses (9), lors du pulse 9 (le dernier) c'est le master qui acquite.
|
||||||
|
* Après chaque acquitement, le Slave amorce le prochain octet en positionnant son bit 7 sur SDA
|
||||||
|
* Après le dernier octet, le Master génère un stop.
|
||||||
|
* Pour pouvoir générer le stop, le Master doit piloter SDA, or ce n'est pas possible puisque
|
||||||
|
le Slave positionne le futur bit 7 ... Pour régler ce problème :
|
||||||
|
lors du dernier transfert, le Master N'acquitte PAS (NACK). Ainsi le Slave ne
|
||||||
|
propose plus le bit 7 du prochain octet sur SDA et libère SDA. Le Master peut alors clôturer la
|
||||||
|
communication avec un Stop.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
======= Echange typique avec un Slave ================================================================
|
||||||
|
- Une lecture ou écriture se fait vers un Slave et à partir d'une adresse mémoire donnée (pointeur interne).
|
||||||
|
Ce pointeur est automatiquement incrémenté dans le slave lors des accès écriture ou lecture.
|
||||||
|
|
||||||
|
- Ecriture de N octets , trame complète (@ = adresse slave, pt = valeur de chargement du pointeur interne)
|
||||||
|
|Start Cond |@6|@5|@4|@3|@2|@1|@0| Wr =0 |Slave ACK|
|
||||||
|
|pt7|pt6|pt5|pt4|pt3|pt2|pt1|pt0|Slave ACK|
|
||||||
|
|d7|d6|d5|d4|d3|d2|d1|d0|Slave ACK| (data 1)
|
||||||
|
.....
|
||||||
|
|d7|d6|d5|d4|d3|d2|d1|d0|Salve ACK|Stop Cond| (data N)
|
||||||
|
|
||||||
|
- Lecture de N octets à partir d'une adresse de pointeur donnée
|
||||||
|
|Start Cond |@6|@5|@4|@3|@2|@1|@0| Wr =0 |Slave ACK|
|
||||||
|
|pt7|pt6|pt5|pt4|pt3|pt2|pt1|pt0|Slave ACK|
|
||||||
|
|ReStart Cond |@6|@5|@4|@3|@2|@1|@0| Wr =1 |Slave ACK| (NB: restart nécessaire pour changer écriture / lecture)
|
||||||
|
|d7|d6|d5|d4|d3|d2|d1|d0|Master ACK| (data 1)
|
||||||
|
.....
|
||||||
|
|d7|d6|d5|d4|d3|d2|d1|d0|Master ACK| (data N-1)
|
||||||
|
|d7|d6|d5|d4|d3|d2|d1|d0|Master NACK|Stop Cond| (data N)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*************************************************************************************
|
||||||
|
==================== La lib I2C ==========================================
|
||||||
|
*************************************************************************************
|
||||||
|
|
||||||
|
3 fonctions essentielles :
|
||||||
|
MyI2C_Init
|
||||||
|
MyI2C_PutString
|
||||||
|
MyI2C_GetString
|
||||||
|
|
||||||
|
1 fonction spéciale : MyI2C_Get_Error
|
||||||
|
|
||||||
|
Les fonctions Put/Get string fonctionnent sur le principe classique décrit précédemment
|
||||||
|
(Slave@, Pter @, Data...).
|
||||||
|
La fonction init prend parmi ses paramètres le nom d'une fct callback d'erreur.
|
||||||
|
En fait, le driver gère en IT les erreurs possibles I2C. La fonction MyI2C_Get_Error permet de
|
||||||
|
recevoir un code erreur.
|
||||||
|
Il est conseillé d'utiliser ce callback. Si on tombe dedans, c'est qu'une erreur s'est produite.
|
||||||
|
Si le code erreur est "inconnu", souvent c'est qu'il y a un soucis à l'adressage slave:
|
||||||
|
Vérifier alors la connectique physique SDA/SCL ainsi que l'alimentation du slave ou tout simplement
|
||||||
|
l'@ slave !
|
||||||
|
|
||||||
|
|
||||||
|
==========================================================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*=========================================================================================
|
||||||
|
GESTION ERREURS
|
||||||
|
========================================================================================= */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
OK,
|
||||||
|
BusError, //
|
||||||
|
AckFail, // Pas,d'ack
|
||||||
|
TimeOut, // SCL est resté plus de 25ms à l'état bas
|
||||||
|
UnknownError // IT erreur déclenchée mais pas de flag explicite ...
|
||||||
|
} MyI2C_Err_Enum;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retourne les erreurs I2C
|
||||||
|
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
|
||||||
|
* @retval Type d'erreur rencontrée , voir MyI2C_Err_Enum
|
||||||
|
*/
|
||||||
|
|
||||||
|
MyI2C_Err_Enum MyI2C_Get_Error(I2C_TypeDef * I2Cx);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*=========================================================================================
|
||||||
|
INITIALISATION I2C
|
||||||
|
========================================================================================= */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialise l'interface I2C (1 ou 2)
|
||||||
|
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
|
||||||
|
* @param char IT_Prio_I2CErr 0 à 15 (utilisé en cas d'erreur, IT courte et non bloquante
|
||||||
|
* @param *ITErr_function : callback à utiliser pour sortir d'un plantage transmission
|
||||||
|
* @retval None
|
||||||
|
* @Example MyI2C_Init(I2C1, 2,My_CallbackErr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
void MyI2C_Init(I2C_TypeDef * I2Cx, char IT_Prio_I2CErr, void (*ITErr_function) (void));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*=========================================================================================
|
||||||
|
EMISSION I2C : PutString
|
||||||
|
========================================================================================= */
|
||||||
|
|
||||||
|
|
||||||
|
// Structure de données pour l'émission ou la réception I2C :
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char SlaveAdress7bits; // l'adresse I2C du slave device
|
||||||
|
char * Ptr_Data; // l'adresse du début de tableau char à recevoir/émettre (tableau en RAM uC)
|
||||||
|
char Nb_Data; // le nbre d'octets à envoyer / recevoir
|
||||||
|
}
|
||||||
|
MyI2C_RecSendData_Typedef;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief|Start Cond |@6|@5|@4|@3|@2|@1|@0| Wr =0 |Slave ACK|
|
||||||
|
|pt7|pt6|pt5|pt4|pt3|pt2|pt1|pt0|Slave ACK|
|
||||||
|
|d7|d6|d5|d4|d3|d2|d1|d0|Slave ACK| (data 1)
|
||||||
|
.....
|
||||||
|
|d7|d6|d5|d4|d3|d2|d1|d0|Salve ACK|Stop Cond| (data N)
|
||||||
|
|
||||||
|
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
|
||||||
|
* @param PteurAdress = adresse de démarrage écriture à l'interieur du slave I2C
|
||||||
|
* @param DataToSend, adresse de la structure qui contient les informations à transmettre
|
||||||
|
voir définition MyI2C_RecSendData_Typedef
|
||||||
|
* @retval None
|
||||||
|
* @Example MyI2C_PutString(I2C1,0xAA, &MyI2C_SendTimeData);
|
||||||
|
* Ecrit dans le slave câblé sur I2C1 à partir de l'@ mémoire interne Slave 0xAA
|
||||||
|
|
||||||
|
*/
|
||||||
|
void MyI2C_PutString(I2C_TypeDef * I2Cx, char PteurAdress, MyI2C_RecSendData_Typedef * DataToSend);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*=========================================================================================
|
||||||
|
Réception I2C : GetString
|
||||||
|
========================================================================================= */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief |Start Cond |@6|@5|@4|@3|@2|@1|@0| Wr =0 |Slave ACK|
|
||||||
|
|pt7|pt6|pt5|pt4|pt3|pt2|pt1|pt0|Slave ACK|
|
||||||
|
|ReStart Cond |@6|@5|@4|@3|@2|@1|@0| Wr =1 |Slave ACK|
|
||||||
|
|d7|d6|d5|d4|d3|d2|d1|d0|Master ACK| (data 1)
|
||||||
|
.....
|
||||||
|
|d7|d6|d5|d4|d3|d2|d1|d0|Master NACK|Stop Cond| (data N)
|
||||||
|
|
||||||
|
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
|
||||||
|
* @param PteurAdress = adresse de démarrage lecture à l'interieur du slave I2C
|
||||||
|
* @param DataToSend, adresse de la structure qui contient les informations nécessaires à la
|
||||||
|
réception des données voir définition MyI2C_RecSendData_Typedef
|
||||||
|
* @retval None
|
||||||
|
* @Example MyI2C_GetString(I2C1,0xAA, &MyI2C_RecevievedTimeData);
|
||||||
|
Lit dans le slave câblé sur I2C1 à partir de l'@ mémoire interne Slave 0xAA
|
||||||
|
*/
|
||||||
|
void MyI2C_GetString(I2C_TypeDef * I2Cx, char PteurAdress, MyI2C_RecSendData_Typedef * DataToReceive);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
129
driver/MySPI.h
Normal file
129
driver/MySPI.h
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
|
||||||
|
#ifndef INC_MYSPI_H_
|
||||||
|
#define INC_MYSPI_H_
|
||||||
|
|
||||||
|
#include "stm32f10x.h"
|
||||||
|
|
||||||
|
/*************************************************************************************
|
||||||
|
===================== By Periph team INSA GEI 2022 ===========================
|
||||||
|
*************************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*************************************************************************************
|
||||||
|
===================== I2C les IO STM32F103 =================================
|
||||||
|
*************************************************************************************
|
||||||
|
Les IO sont pris en charge par la lib, pas besoin de faire les configurations
|
||||||
|
|
||||||
|
|
||||||
|
Sur la Nucléo , le SPI1 est perturbé par la LED2 (PA5), mais doit pouvoir subir les front SCK qd même (LED clignote vite..)
|
||||||
|
le SPI2 n'est pas utilisable car pin non connectées par défaut (sauf à modifier les SB). En fait la Nucléo fait un choix entre SPI1
|
||||||
|
et SPI2 par soudage jumper (SB).
|
||||||
|
|
||||||
|
-> Utiliser SPI1 avec la carte Nucléo
|
||||||
|
|
||||||
|
* **IO SPI 1**
|
||||||
|
SPI1_NSS PA4
|
||||||
|
SPI1_SCK PA5
|
||||||
|
SPI1_MISO PA6
|
||||||
|
SPI1_MOSI PA7
|
||||||
|
|
||||||
|
**IO SPI 2**
|
||||||
|
SPI2_NSS PB12
|
||||||
|
SPI2_SCK PB13
|
||||||
|
SPI2_MISO PB14
|
||||||
|
SPI2_MOSI PB15
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*************************************************************************************
|
||||||
|
==================== Fondamentaux SPI ==========================================
|
||||||
|
*************************************************************************************
|
||||||
|
- Bus Synchrone, 4 fils (même si on peut l'utiliser en 3 fils)
|
||||||
|
- Transfert à l'octet
|
||||||
|
- Protocole entre un Master (contrôle SCK) et un Slave
|
||||||
|
- SCK permet de synchroniser les bits de chaque octet. Il se configure par :
|
||||||
|
* son niveau de repos : ici niveau '1'
|
||||||
|
* le front actif de synchronisation pour chaque bit : ici front montant (front up durant bit stable)
|
||||||
|
- /CS ou /NSS active le slave sur l'état bas
|
||||||
|
- MOSI : Master Out Slave In (donc data circulant du Master vers le Slave, donc écriture dans le Slave)
|
||||||
|
- MISO : Master In Slave Out (donc data circulant du Slave vers le Master, donc lecture du Slave)
|
||||||
|
|
||||||
|
Bien que la lib propose une fonction d'écriture et de lecture :
|
||||||
|
* une écriture s'accompagne obligatoirement d'une lecture (bidon)
|
||||||
|
* une lecture s'accompagne obligatoirement d'une écriture (bidon)
|
||||||
|
La gestion /CS = /NSS se fait "à la main". On peut alors lire toute une série d'octets
|
||||||
|
en laissant /CS à l'état bas pendant toute la durée de circulation des octets.
|
||||||
|
|
||||||
|
|
||||||
|
*************************************************************************************
|
||||||
|
==================== La lib SPI ==========================================
|
||||||
|
*************************************************************************************
|
||||||
|
|
||||||
|
fonctions essentielles :
|
||||||
|
|
||||||
|
MySPI_Init
|
||||||
|
MySPI_Send
|
||||||
|
MySPI_Read
|
||||||
|
MySPI_Set_NSS
|
||||||
|
MySPI_Clear_NSS
|
||||||
|
|
||||||
|
|
||||||
|
==========================================================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*=========================================================================================
|
||||||
|
INITIALISATION SPI
|
||||||
|
========================================================================================= */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure le SPI spécifié : FSCK = 281kHz, Repos SCK = '1', Front actif = up
|
||||||
|
Gestion /CS logicielle à part, configure les 4 IO
|
||||||
|
- SCK, MOSI : Out Alt push pull
|
||||||
|
- MISO : floating input
|
||||||
|
- /NSS (/CS) : Out push pull
|
||||||
|
* @param SPI_TypeDef * SPI : SPI1 ou SPI2
|
||||||
|
*/
|
||||||
|
void MySPI_Init(SPI_TypeDef * SPI);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Envoie un octet (/CS non géré, à faire logiciellement)
|
||||||
|
Plus en détail, émission de l'octet souhaité sur MOSI
|
||||||
|
Lecture en même temps d'un octet poubelle sur MISO (non exploité)
|
||||||
|
* @param : char ByteToSend : l'octet à envoyer
|
||||||
|
*/
|
||||||
|
void MySPI_Send(char ByteToSend);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reçoit un octet (/CS non géré, à faire logiciellement)
|
||||||
|
Plus en détail, émission d'un octet bidon sur MOSI (0x00)
|
||||||
|
pour élaborer les 8 fronts sur SCK et donc piloter le slave en lecture
|
||||||
|
qui répond sur MISO
|
||||||
|
* @param : none
|
||||||
|
* @retval : l'octet lu.
|
||||||
|
*/
|
||||||
|
char MySPI_Read(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Positionne /CS = /NSS à '1'. A utiliser pour borner les octets à transmettre/recevoir
|
||||||
|
* @param : none
|
||||||
|
*/
|
||||||
|
void MySPI_Set_NSS(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Positionne /CS = /NSS à '0'. A utiliser pour borner les octets à transmettre/recevoir
|
||||||
|
* @param :none
|
||||||
|
*/
|
||||||
|
void MySPI_Clear_NSS(void);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue