This commit is contained in:
Angoosh Leviocki 2021-07-01 14:12:44 +02:00
parent 4d4b706a3d
commit 1ed9449d96
15 changed files with 1170 additions and 3 deletions

16
ADC.c Normal file
View File

@ -0,0 +1,16 @@
uint32_t SingleChannel(ADC_HandleTypeDef* hadc){
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion (hadc, 100);
uint32_t x = HAL_ADC_GetValue(hadc);
HAL_ADC_Stop(&hadc);
return x;
}
void MultiChannel(ADC_HandleTypeDef *hadc, uint32_t *outbuffer, uint8_t n_of_channels){
HAL_ADC_Start(hadc);
for(uint8_t i = 0; i<n_of_channels; i++){
HAL_ADC_PollForConversion (hadc, 100);
outbuffer[i] = HAL_ADC_GetValue(hadc);
HAL_ADC_Stop(hadc);
}
}

452
Alink.c Normal file
View File

@ -0,0 +1,452 @@
//************************************************************************************
//**************** Alink (c) Angoosh *****************
//**************** ADCIS s.r.o. *****************
//**************** Alink *****************
// ver 1.0.0
// 11.11.2019
//************************************************************************************
#include "Alink.h"
#include "main.h"
//void checkA5(uint8_t, uint8_t, uint8_t);
void TxParseMSG(UART_HandleTypeDef*,int,uint8_t,uint8_t,uint8_t);
void RxParseMSG(UART_HandleTypeDef*,uint8_t*);
/*
* Vysilani zpravy: A5, rec add, ln, my add, 0, data, CRC
* 0 verze sw: A5, rec add, 0C, ADDRESS, 0, VERSION, SUB_VERSION, RELEASE, BUGFIX, CRC
* 1 status: A5, rec add, 08, ADDRESS, 0, STATUS, CRC
* 2 err: A5, rec add, 08, ADDRESS, 1, ERROR, CRC
*
* parametry fce:
* type: 0,1,2 (verze, status, err)
* mess: 0,1,2 (verze - pouze 0, status - 1,2,3, err - 1,2)
*
*
* data bit:
* 0 - version
* 1 - status - sleep
* 2 - status - charging
* 3 - status - running
* 4 - err - UNDERVOLT
* 5 - err - FET_ERR
*/
/**
* @brief A5 symbol replacement pattern find
* @param checked byte
* @param retval for first replacement byte
* @param retval for second replacement byte
*/
void checkA5(uint8_t byte, uint8_t *arr1, uint8_t *arr2){ //kontrola, zda ve zprave neni A5
if(byte == 0xA5){
*arr1 = 0xAA;
*arr2 = 0xA8;
}
else if(byte == 0xAA){
*arr1 = 0xAA;
*arr2 = 0xAA;
}
else{
*arr1 = byte;
*arr2 = 0x00;
}
}
void A5pattern(uint8_t *messageIn, uint8_t *messageOut){
}
/**
* @brief CRC calculation function
* @param data array pointer
* @param data length
* @retval crc byte
*/
uint8_t CRC_Calc(uint8_t *data, uint8_t length){
uint8_t crc = 0;
for(int i = 0; i<length; i++){
crc ^= data[i];
}
return crc;
}
/**
* @brief Receive message parser and command executer
* @param huart typedef
* @param message
*/
void RxParseMSG(UART_HandleTypeDef *huart, uint8_t *dataBuffer){
uint8_t isLCB = 0;
//uint8_t msgMyAddr = dataBuffer[1];
uint8_t msgLen = dataBuffer[2];
uint8_t msgTxAddr = dataBuffer[3];
uint8_t msgCmd = dataBuffer[4];
uint8_t msgCrc = dataBuffer[msgLen-1];
uint8_t msgPreData[msgLen-6];
if(msgLen > 6){
for(int i = 0; i<sizeof(msgPreData); i++){
msgPreData[i] = dataBuffer[5+i];
}
}
uint8_t payload = 0;
uint8_t msgForCrc[msgLen-2];
for(int m = 0; m<sizeof(msgForCrc); m++){
msgForCrc[m] = dataBuffer[m+1];
}
if(msgCrc == CRC_Calc(msgForCrc, sizeof(msgForCrc))){
if(msgTxAddr >= LCBADDRMIN && msgTxAddr <= LCBADDRMAX){
isLCB = 1;
}
}
uint8_t AAcount = 0;
for(int i = 0; i<sizeof(msgPreData); i++){
if(msgPreData[i] == 0xAA){
AAcount++;
i++;
}
}
uint8_t msgData[sizeof(msgPreData)-AAcount];
uint8_t j = 0;
for(int i = 0; i<sizeof(msgPreData); i++){
if(msgPreData[i+j] == 0xAA){
if(msgPreData[i+j+1] == 0xAA){
msgData[i] = 0xAA;
}
else{
msgData[i] = 0xA5;
}
j++;
}
else{
msgData[i] = msgPreData[i+j];
}
}
if(isLCB == 1){
if(msgLen > 6){
payload = 1;
}
if(msgCmd == SW_VER_ASK){ //verze sw //type 0
TxParseMSG(huart,0,0x00,0x00,msgTxAddr);
}
else if(msgCmd == STATUS){ //stav (charging, off, on) //type 1
uint8_t msgStatus = 0;
TxParseMSG(huart,1,0x00,msgStatus,msgTxAddr);
}
else if(msgCmd == STATE_ASK){ //status (err) //type 2
uint8_t msgState = 0;
TxParseMSG(huart,2,0x00,msgState,msgTxAddr);
}
#ifdef ALINK_CTRL
else if(msgCmd == ALINK_STABLE_STATE && payload == 1){//zapnuti/vypnuti ustaleneho stavu, default je vyply
SteadyState = msgData[0];
}
else if(msgCmd == ALINK_BLOCK_PLS && payload == 1){//vyber ktere pulsy blokovat, popis funkce je v @info
if(msgData[0] == 0x00){
for(int i = 0; i < 8; i++){
INJ0.PULSE_DEL_ARR[i] = msgData[1+i];
}
}
else if(msgData[0] == 0x01){
for(int i = 0; i < 8; i++){
INJ1.PULSE_DEL_ARR[i] = msgData[1+i];
}
}
else if(msgData[0] == 0x02){
for(int i = 0; i < 8; i++){
INJ2.PULSE_DEL_ARR[i] = msgData[1+i];
}
}
else;
}
else if(msgCmd == ALINK_BLOCK_PLS_END && payload == 1){//vyber po ktere pulsy blokovat, popis funkce je v @info
if(msgData[0] == 0x00){
for(int i = 0; i < 8; i++){
INJ0.PULSE_DEL_END_ARR[i] = msgData[1+i];
}
}
else if(msgData[0] == 0x01){
for(int i = 0; i < 8; i++){
INJ1.PULSE_DEL_END_ARR[i] = msgData[1+i];
}
}
else if(msgData[0] == 0x02){
for(int i = 0; i < 8; i++){
INJ2.PULSE_DEL_END_ARR[i] = msgData[1+i];
}
}
else;
}
else if(msgCmd == ALINK_FET_SW_PAUSE && payload == 1){//Nastaveni delky pauzy mezi prepinani fetu
int hi = msgData[1];
int lo = msgData[2];
int delay = (hi*256)+lo;
if(msgData[0] == 0x00){
INJ0.SWITCH_DELAY = SwitchDelaySetup(INJ0, delay);
}
else if(msgData[0] == 0x01){
INJ1.SWITCH_DELAY = SwitchDelaySetup(INJ1, delay);
}
else if(msgData[0] == 0x02){
INJ2.SWITCH_DELAY = SwitchDelaySetup(INJ2, delay);
}
else;
}
else if(msgCmd == ALINK_PULSE_BLK_TIM && payload == 1){//po kolika ms blokovat puls 2B
uint8_t hi = msgData[1];
uint8_t lo = msgData[2];
float ARR = 65535;
float PSC = 53;
float x = (1/(SysClk/APBDiv))*(PSC+1)*(ARR+1)*1000;
float us = (x/ARR)*1000;
int BlockPulseAfterMs = (hi*256)+lo;
int BlockPulseAfterTicks = BlockPulseAfterMs/us;
if(msgData[0] == 0x00){
INJ0.BLOCK_AFTER_TICKS = BlockPulseAfterTicks;
INJ0.BLOCK_AFTER_US = BlockPulseAfterMs;
}
else if(msgData[0] == 0x01){
INJ1.BLOCK_AFTER_TICKS = BlockPulseAfterTicks;
INJ1.BLOCK_AFTER_US = BlockPulseAfterMs;
}
else if(msgData[0] == 0x02){
INJ2.BLOCK_AFTER_TICKS = BlockPulseAfterTicks;
INJ2.BLOCK_AFTER_US = BlockPulseAfterMs;
}
else;
}
#ifdef ALINK_BRD_RST
else if(msgData[0] == ALINK_BRD_RST){
TxParseMSG(huart,3,0x00,msgData[0],msgTxAddr);
HAL_NVIC_SystemReset();
}
#endif
}
#endif
else;
}
/**
* @brief Response message parser
* @param huart typedef
* @param type of message
* @param command
* @param data of message
* @param address of destination device
*/
void TxParseMSG(UART_HandleTypeDef *huart, int type, uint8_t CMD, uint8_t mess, uint8_t addr){
uint8_t crc = 0;
int datasize = 0;
uint8_t data_buffer[40];
uint8_t data_buffer_size = 0;
//verze softwaru
if(type == 0){
uint8_t data[] = {addr,0x0A,ADDRESS,CMD,VERSION,SUB_VERSION,RELEASE,BUGFIX};
datasize = sizeof(data);
for(int i = 0; i<sizeof(data); i++){
uint8_t a,b;
checkA5(data[i], &a, &b);
if(a != 0 && b != 0){
datasize ++;
data[1]++;
}
}
datasize ++;
uint8_t datanew[datasize];
datanew[0] = 0xA5;
int j = 0;
for(int i = 1; i<sizeof(datanew); i++){
uint8_t a,b;
checkA5(data[i-1], &a, &b);
if(a != 0 && b != 0){
datanew[i+j] = a;
datanew[i+j+1] = b;
j++;
}
else{
datanew[i+j] = a;
}
}
for(int i = 0; i<sizeof(datanew); i++){
data_buffer[i] = datanew[i];
data_buffer_size ++;
}
uint8_t dataForCrc[sizeof(datanew-1)];
for(int i = 0; i < sizeof(dataForCrc); i++){
dataForCrc[i] = datanew[i+1];
}
crc = CRC_Calc(dataForCrc,sizeof(dataForCrc));
}
//status
else if(type == 1){
__IO uint32_t DATA_READ = 0;
uint8_t data[] = {addr,0x13,ADDRESS,CMD,mess,0,0,0,0,0,0,0,0,0,0,0,0};
datasize = sizeof(data);
DATA_READ = *(__IO uint32_t*)SERIAL_ADDRESS;
data[13] = DATA_READ >> 24;
data[14] = DATA_READ >> 16;
data[15] = DATA_READ >> 8;
data[16] = DATA_READ;
for(int i = 0; i<sizeof(data); i++){
uint8_t a,b;
checkA5(data[i], &a, &b);
if(a != 0 && b != 0){
datasize ++;
data[1]++;
}
}
datasize ++;
uint8_t datanew[datasize];
datanew[0] = 0xA5;
int j = 0;
for(int i = 1; i<sizeof(datanew); i++){
uint8_t a,b;
checkA5(data[i-1], &a, &b);
if(a != 0 && b != 0){
datanew[j+i] = a;
datanew[j+i+1] = b;
j++;
}
else{
datanew[j+i] = a;
}
}
for(int i = 0; i<sizeof(datanew); i++){
data_buffer[i] = datanew[i];
data_buffer_size ++;
}
uint8_t dataForCrc[sizeof(datanew-1)];
for(int i = 0; i < sizeof(dataForCrc); i++){
dataForCrc[i] = datanew[i+1];
}
crc = CRC_Calc(dataForCrc,sizeof(dataForCrc));
}
//error report
else if(type == 2){
uint8_t data[] = {addr,0x07,ADDRESS,CMD,mess};
datasize = sizeof(data);
for(int i = 0; i<sizeof(data); i++){
uint8_t a,b;
checkA5(data[i], &a, &b);
if(a != 0 && b != 0){
datasize ++;
data[1]++;
}
}
datasize ++;
uint8_t datanew[datasize];
datanew[0] = 0xA5;
int j = 0;
for(int i = 1; i<sizeof(datanew); i++){
uint8_t a,b;
checkA5(data[i-1], &a, &b);
if(a != 0 && b != 0){
datanew[j+i] = a;
datanew[j+i+1] = b;
j++;
}
else{
datanew[j+i] = a;
}
}
for(int i = 0; i<sizeof(datanew); i++){
data_buffer[i] = datanew[i];
data_buffer_size ++;
}
uint8_t dataForCrc[sizeof(datanew-1)];
for(int i = 0; i < sizeof(dataForCrc); i++){
dataForCrc[i] = datanew[i+1];
}
crc = CRC_Calc(dataForCrc,sizeof(dataForCrc));
}
//else messages
else if(type == 3){
uint8_t data[] = {addr,0x07,ADDRESS,CMD,mess};
datasize = sizeof(data);
for(int i = 0; i<sizeof(data); i++){
uint8_t a,b;
checkA5(data[i], &a, &b);
if(a != 0 && b != 0){
datasize ++;
data[1]++;
}
}
datasize ++;
uint8_t datanew[datasize];
datanew[0] = 0xA5;
int j = 0;
for(int i = 1; i<sizeof(datanew); i++){
uint8_t a,b;
checkA5(data[i-1], &a, &b);
if(a != 0 && b != 0){
datanew[j+i] = a;
datanew[j+i+1] = b;
j++;
}
else{
datanew[j+i] = a;
}
}
for(int i = 0; i<sizeof(datanew); i++){
data_buffer[i] = datanew[i];
data_buffer_size ++;
}
uint8_t dataForCrc[sizeof(datanew-1)];
for(int i = 0; i < sizeof(dataForCrc); i++){
dataForCrc[i] = datanew[i+1];
}
crc = CRC_Calc(dataForCrc,sizeof(dataForCrc));
}
else{}
datasize ++;
uint8_t a,b;
checkA5(crc, &a, &b);
if(a != 0 && b != 0){
datasize ++;
uint8_t msg[datasize];
for(int i = 0; i<datasize-2; i++){
msg[i] = data_buffer[i];
}
msg[sizeof(msg)-2] = a;
msg[sizeof(msg)-1] = b;
msg[2]++;
HAL_UART_Transmit(huart, (uint8_t *)&msg, sizeof(msg), 0xFFFF);
}
else{
uint8_t msg[datasize];
for(int i = 0; i<datasize-1; i++){
msg[i] = data_buffer[i];
}
msg[sizeof(msg)-1] = a;
HAL_UART_Transmit(huart, (uint8_t *)&msg, sizeof(msg), 0xFFFF);
}
}

62
Alink.h Normal file
View File

@ -0,0 +1,62 @@
/*
* Alink.h
*
* Created on: 16. 6. 2020
* Author: Adcis
*/
#ifndef INC_ALINK_H_
#define INC_ALINK_H_
#include "main.h"
#define ALINK_CTL_ENABLE //povoleni rizeni pres Alink
#define VERSION 0x02 //verze hardware
#define SUB_VERSION 0x01 //verze software
#define RELEASE 0x00 //je = 1 / neni = 0 release verze softwaru
#define BUGFIX 0x00 //cislo bugfixu (HW verze desky)
//Flash data
#define SERIAL_ADDRESS ((uint32_t)0x0800F000)
#define ALINK_CTL_ADDRESS ((uint32_t)0x0800F400)
#define ALINK_CTLB_ADDRES ((uint32_t)0x0800F404)
#define CALIB_ADDRESS ((uint32_t)0x0800FC00)
//komunikace
#define CRC_CHCK
#define ADDRESS 0x31 //adresa desky na SS sbernici
#define DEF_BYTES_IN_RX 0xFF //velikost RX bufferu
#define RX_BUFFER DEF_BYTES_IN_RX
#define DEBUG_BUFFER 0xFF
#define COMMAND_MASK 0x7F
#define BROADCAST_MSK 0x80
#define STATE_ASK 0x03 //otazka na stav desky (errory) //0x03
#define STATE_REPLY 0x04 //odpoved na stav //0x04
#define SW_VER_ASK 0x05 //otazka na verzi sw //0x05
#define STATUS 0x06 //otazka na status chyb //0x06
#define ALINK_TOGGLE 0x40 //toggle Alink rizeni
//address space
#define LCBADDRMIN 0x10
#define LCBADDRMAX 0x17
#ifdef ALINK_CTL_ENABLE
#define ALINK_CTRL 0x30 //prikaz pro manualni rizeni
#define ALINK_CHARGE_ON 0x01 //turn on charging
#define ALINK_CHARGE_OFF 0x00 //turn off charging
#define ALINK_RE_ERR_ON 0x02 //turn on RE_ERR
#define ALINK_RE_ERR_OFF 0x03 //turn off RE_ERR
#define ALINK_EMERG_STOP 0x10 //emergency state of softstart disable
#define ALINK_EMERG_GO 0x11 //emergency state of softstart enable
#define ALINK_FLASH_SN 0x20 //flash serial number
#define ALINK_CRG_CAL 0x21 //calibrate charging by C-
#define ALINK_BRD_RST 0xFA //reset whole board - comment to disable
#endif
void TxParseMSG(UART_HandleTypeDef *huart, int type, uint8_t CMD, uint8_t mess, uint8_t addr);
void RxParseMSG(UART_HandleTypeDef *huart, uint8_t *dataBuffer);
#endif /* INC_ALINK_H_ */

24
GPIO.c Normal file
View File

@ -0,0 +1,24 @@
/*
GPIO obsaahhuje brany a piny jednotlivych bran, takze kdyz chcem nastavit pin PB0 HIGH
tak je prikaz GPIO(GPIOB, GPIO_PIN_0, 1)
cisty call na registr by byl
GPIOB->BSRR |= 1 << 0;
*/
//STM32F4
void GPIO(GPIO_TypeDef* GPIOx, uint16_t pin, uint8_t state){
if(state == 0){
GPIOx->BSRR = (uint32_t)pin << 16U;
}
else{
GPIOx->BSRR = pin;
}
//STM32F0
void GPIO(GPIO_TypeDef* GPIOx, uint16_t pin, uint8_t state){
if(state == 0){
GPIOx->BRR = pin;
}
else{
GPIOx->BSRR = pin;
}

View File

@ -1,3 +1,3 @@
# STM32_Examples # STM32 Examples
Example code for STM32 MCUs Examples for STM32 MCUs

60
STM_Flash.c Normal file
View File

@ -0,0 +1,60 @@
void Flash(uint32_t address, uint32_t data, uint16_t datasize, char operation){
if(operation == 1){
HAL_FLASH_Unlock();
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = address;
EraseInitStruct.NbPages = 1U;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK){
Error_Handler();
}
addressNew = address;
//while (Address < SECTOR_63){
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addressNew, data) == HAL_OK){
addressNew = addressNew + 4;
}
else
{
Error_Handler();
}
//}
HAL_FLASH_Lock();
DATA_READ = *(__IO uint32_t*)addressNew;
if(DATA_READ == data){
GPIOA->BSRR = DE_Pin;
char msg[9] = {"Flash OK"};
HAL_UART_Transmit(&huart2, (uint8_t *)&msg, sizeof(msg), 0xFFFF);
GPIOA->BRR = DE_Pin;
}
else{
GPIOA->BSRR = DE_Pin;
uint8_t msg[datasize];
for(int i = 0; i<sizeof(msg); i++){
msg[i] = 0;
}
msg[0] = DATA_READ >> 24;
msg[1] = DATA_READ >> 16;
msg[2] = DATA_READ >> 8;
msg[3] = DATA_READ;
HAL_UART_Transmit(&huart2, (uint8_t *)&msg, sizeof(msg), 0xFFFF);
GPIOA->BRR = DE_Pin;
}
}
else{
DATA_READ = *(__IO uint32_t*)address;
GPIOA->BSRR = DE_Pin;
uint8_t msg[4] = {0,0,0,0};
msg[0] = DATA_READ >> 24;
msg[1] = DATA_READ >> 16;
msg[2] = DATA_READ >> 8;
msg[3] = DATA_READ;
HAL_UART_Transmit(&huart2, (uint8_t *)&msg, sizeof(msg), 0xFFFF);
GPIOA->BRR = DE_Pin;
}
}

17
STM_WatchDog.c Normal file
View File

@ -0,0 +1,17 @@
void wdt_enable(void)
{
RCC -> CSR = RCC -> CSR | 0x00000001; //Enable LSI Clock
while((RCC -> CSR & 0x02)==0)
{
//add timeout code here
}
IWDG -> KR = 0x0000CCCC; //Enable IWDG
IWDG -> KR = 0x00005555; //Enable register access
IWDG -> PR = 0x010; //Set Prescaler /16
IWDG -> RLR = 0xFFF; //Set Reload Value for 2.048 seconds
while(IWDG -> SR) //Check if flags are reset
{
//add timeout code here
}
IWDG -> KR = 0x0000AAAA; //Refresh the counter
}

210
Soft_SPI.c Normal file
View File

@ -0,0 +1,210 @@
/*
* Soft_SPI.c
*
* Created on: Nov 26, 2019
* Author: Adcis
*
* SCK_Pin, MOSI_Pin, MISO_Pin, CS0_Pin and CS1_Pin required to define in project
*
* Software SPI library for use with STM32 MCUs
*/
#include "main.h"
#include "Soft_SPI.h"
//#include "main.c"
void SOFT_Power(int,int);
void SOFT_SCK(unsigned int); //rizeni SCK pinu
void SOFT_SPI(unsigned int); //rizeni MOSI pinu
void SOFT_SPI_Send(unsigned int); //odeslani zpravy po SPI
int SOFT_SPI_Receive(unsigned int); //prijem zpravy po SPI
void SOFT_CS(unsigned int); //chip select - 0 = DA prevodnik, 1 = AD prevodnik, cokoliv jineho = nezvoleno nic
void SOFT_SPI_CLK(unsigned int); //1 puls _|-|_ na SCK
int SOFT_Power(int x, int y){
if (y == 0){
return 1;
}
else if (y % 2 == 0){
return SOFT_Power(x, y / 2) * SOFT_Power(x, y / 2);
}
else{
return x * SOFT_Power(x, y / 2) * SOFT_Power(x, y / 2);
}
}
/**
* @brief Controls SCK
*
* @param var = set state of SCK
*
* @retval None
*/
void SOFT_SCK(unsigned int state){
if(state == 1){
GPIOB->BSRR = SCK_Pin;
}
else{
GPIOB->BRR = SCK_Pin;
}
}
/**
* @brief Controls MOSI
*
* @param var = set state of MOSI
*
* @retval None
*/
void SOFT_SPI(unsigned int var){
if(var!=0){
GPIOB->BSRR = MOSI_Pin;
}
else{
GPIOB->BRR = MOSI_Pin;
}
}
/**
* @brief SPI CS control
*
* @param cs = what cs pin to use
*
* @retval None
*/
void SOFT_CS(unsigned int cs){
if(cs == 0){
GPIOB->BSRR = CS1_Pin;
GPIOB->BRR = CS0_Pin;
}
else if(cs == 1){
GPIOB->BSRR = CS0_Pin;
GPIOB->BRR = CS1_Pin;
}
else{
GPIOB->BSRR = CS0_Pin;
GPIOB->BSRR = CS1_Pin;
}
}
/**
* @brief Sends SPI message
*
* @param value = what byte to send
*
* @retval None
*/
void SOFT_SPI_Send(unsigned int value){
unsigned int valueBin[] = {0,0,0,0,0,0,0,0};
if(value >= 128){
valueBin[0] = 1;
value = value % 128;
}
if(value >= 64){
valueBin[1] = 1;
value = value % 64;
}
if(value >= 32){
valueBin[2] = 1;
value = value % 32;
}
if(value >= 16){
valueBin[3] = 1;
value = value % 16;
}
if(value >= 8){
valueBin[4] = 1;
value = value % 8;
}
if(value >= 4){
valueBin[5] = 1;
value = value % 4;
}
if(value >= 2){
valueBin[6] = 1;
}
valueBin[7] = value % 2;
SOFT_SCK(0);
SOFT_SPI(valueBin[0]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[1]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[2]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[3]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[4]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[5]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[6]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[7]);
SOFT_SCK(0);
SOFT_SCK(1);
GPIOB->BRR = MOSI_Pin;
SOFT_SCK(0);
}
/**
* @brief Recieves SPI message
*
* @param bits = how long will received mesage be
*
* @retval uint16_t
*/
int SOFT_SPI_Receive(unsigned int bits){
uint8_t arr_bts[bits];
uint8_t sumarr[bits];
uint16_t sum;
for(int i=0; i<bits;i++){
SOFT_SCK(1);
if(HAL_GPIO_ReadPin(GPIOB, MISO_Pin) == 1){
arr_bts[i] = 1;
}
else{
arr_bts[i] = 0;
}
#ifndef FAST_SPI
sumarr[i] = arr_bts[i] * power(2 , bits - i - 1);
#endif
SOFT_SCK(0);
}
#ifdef FAST_SPI
for(int i = 0; i < bits; i++){
sumarr[i] = arr_bts[i] * SOFT_Power(2 , bits - i - 1);
}
#endif
//receive string
if(bits==12){
sum = sumarr[0]+sumarr[1]+sumarr[2]+sumarr[3]+sumarr[4]+sumarr[5]+sumarr[6]+sumarr[7]+sumarr[8]+sumarr[9]+sumarr[10]+sumarr[11];
}
else if(bits==16){
sum = sumarr[0]+sumarr[1]+sumarr[2]+sumarr[3]+sumarr[4]+sumarr[5]+sumarr[6]+sumarr[7]+sumarr[8]+sumarr[9]+sumarr[10]+sumarr[11]+sumarr[12]+sumarr[13]+sumarr[14]+sumarr[15];
}
else if(bits==8){
sum = sumarr[0]+sumarr[1]+sumarr[2]+sumarr[3]+sumarr[4]+sumarr[5]+sumarr[6]+sumarr[7];
}
else{
sum = 0;
}
return sum;
}
/**
* @brief SPI clk
*
* @param cycles = how many cycles to make
*
* @retval None
*/
void SOFT_SPI_CLK(unsigned int cycles){
for(int i=0;i<cycles;i++){
SOFT_SCK(1);
for(int j=0;j<1;j++);
SOFT_SCK(0);
}
}

8
Soft_SPI.h Normal file
View File

@ -0,0 +1,8 @@
void SOFT_SCK(unsigned int state); //rizeni SCK pinu
void SOFT_SPI(unsigned int var); //rizeni MOSI pinu
void SOFT_SPI_Send(unsigned int value); //odeslani zpravy po SPI
int SOFT_SPI_Receive(unsigned int bits); //prijem zpravy po SPI
void SOFT_CS(unsigned int cs); //chip select - 0 = DA prevodnik, 1 = AD prevodnik, cokoliv jineho = nezvoleno nic
void SOFT_SPI_CLK(unsigned int cycles); //1 puls _|-|_ na SCK
#define FAST_SPI

31
TIM.c Normal file
View File

@ -0,0 +1,31 @@
//prescaler formula for period:
//T = (1/APB_TIM_CLK in Hz) * (PRESCALER_Value + 1) * (PERIOD_Value (ARR register) + 1)
/* Assymetric PWM mode:
* CH1 & CH2 are switched to center alligned mode, when chosen more than 2 channels in Assymetric mode, the
* rest will be in normal PWM mode.
* TIMx->CCR1 controls length of CH1 pulse after center and length of CH2 pulse before center.
* TIMx->CCR2 controls length of CH1 pulse before center and length of CH2 pulse after center.
* TIMx->CCR3,4 controls length of CH3,4 pulse after center
*/
/* PWM dynamic duty cycle:
* TIMx->CCMRxOutput ->-> OCxPE = 1 // setup of shaddow register
* TIMx->CCRx = x // set pulse length
* shaddow register is important for stability of program, because the new value will be written, when new
* cycle is begun.
*/
//enable period elapsed callback
TIM3->DIER |= 1 << 0;
//callbacks
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim -> Instance == TIM3){
}
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){
if(htim -> Instance == TIM3){
}
}

43
Trace_debug.md Normal file
View File

@ -0,0 +1,43 @@
# All you need to know
## Debugger modification:
connect PA10 (pin 31) to one of the debugger pins for example to one of the 5V pins.
## Software
### printf adaptation:
For printf function to work we need _write method.<br/>
```c
int _write(int file, char *ptr, int len){
int DataIdx;
for(DataIdx=0; DataIdx<len; DataIdx++){
ITM_SendChar(*ptr++);
}
return len;
}
```
### Cube IDE setup:
In .IOC perspective in system core tab select Trace Asynchronous Sw<br/>
Make sure you know core frequency.<br/>
<br/>
Initial code:<br/>
```c
#include stdio.h
#define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*n)))
```
Example code before while loop:<br/>
```c
SystemClock_Config();
ITM_Port32(31) = 1;
MX_GPIO_Init();
printf("gpio init done \r\n");
ITM_Port32(31) = 2;
```
In debug configuration enable SWV and make sure Core clock matches clock of processor<br/>
For view the trace data go to Window>Show view>SWV<br/>
<br/>
M0 and M0+ cortex MCUs are not supported<br/>
Make sure, that you have selected output port in "Configure trace"
For more info: https://www.youtube.com/watch?list=PLXnwAHPMBciEfY6C6rnz6rUehFxCQMwzY&v=4wT9NhlcWP4&feature=emb_title

115
UART.c Normal file
View File

@ -0,0 +1,115 @@
//##Interrupt receive per character
uint8_t WholeRxBuffer[256];
uint8_t RX[1];
uint8_t ptr = 0;
//setup
HAL_UART_Receive_IT(&huart3, RX, 1);
//callback
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
WholeRxBuffer[ptr] = RX[0];
ptr++;
HAL_UART_Receive_IT(&huart3, RX, 1);
}
//##DMA receive
//je potreba povolit DMA na uart RX
#include "Alink.h"
uint8_t readBuffer[RX_BUFFER];
uint8_t RX[RX_BUFFER];
//inicializace uartu - interface,buffer,velikost zpravy
HAL_UART_Receive_DMA(&huart1,readBuffer,sizeof(readBuffer));
//vysilani zpravy
HAL_UART_Transmit(&huart1, (uint8_t *)&"\nThe cake is a lie", 18, 0xFFFF);
//presouvani dat z prijimaciho bufferu do cteciho bufferu (prijimaci buffer se ctenim maze)
for(int i = 0; i<sizeof(readBuffer); i++){
RX[i] = readBuffer[i];
readBuffer[i] = 0;
}
//cteni dat z cteciho bufferu a reseni zprav
for(int u = 0; u<sizeof(RX); u++){
u += listVar(u);
}
//funkce pro reseni prichozich zprav
uint8_t listVar(uint8_t index){
uint8_t msgLen = 0;
uint8_t senderAddr = 0;
uint8_t cmd = 0;
uint8_t crc = 0;
if(RX[index] == 0xA5){
if(RX[index+1] == ADDRESS){
msgLen = RX[index+2];
senderAddr = RX[index+3];
cmd = RX[index+4];
crc = RX[index+msgLen-1];
if(msgLen > 6){
uint8_t data[msgLen-6];
for(int i = 0; i<sizeof(data); i++){
data[i] = RX[index+5+i];
}
//zpracovani dat v Alinku
uint8_t inputArray[msgLen];
inputArray[0] = 0xA5;
inputArray[1] = ADDRESS;
inputArray[2] = msgLen;
inputArray[3] = senderAddr;
inputArray[4] = cmd;
inputArray[msgLen-1] = crc;
for(int i = 0; i<sizeof(data); i++){
inputArray[5+i] = data[i];
}
RxParseMSG(&huart1, inputArray);
}
else{
//zpracovani dat v Alinku
uint8_t inputArray[msgLen];
inputArray[0] = 0xA5;
inputArray[1] = ADDRESS;
inputArray[2] = msgLen;
inputArray[3] = senderAddr;
inputArray[4] = cmd;
inputArray[5] = crc;
RxParseMSG(&huart1, inputArray);
}
}
if(msgLen != 0){
return msgLen-1;
}
else{
return 0;
}
}
else{
return 0;
}
}
//int to str conversion
void dbg(unsigned long n){//16.7
char operator = '+';
if(n > 4294967296/2){
n = 4294967296 - n;
operator = '-';
}
char tmp[11];
int i = sizeof(tmp);
for(int j = 0; j<i-1; j++){
tmp[j] = '0';
}
do
{
tmp[--i] = '0' + n % 10;
n /= 10;
} while (n);
HAL_UART_Transmit(&huart7, (uint8_t *)&operator, 1, 0xFFFF);
HAL_UART_Transmit(&huart7, (uint8_t *)&tmp, sizeof(tmp), 0xFFFF);
}

94
printf/retarget.c Normal file
View File

@ -0,0 +1,94 @@
// All credit to Carmine Noviello for this code
// https://github.com/cnoviello/mastering-stm32/blob/master/nucleo-f030R8/system/src/retarget/retarget.c
#include <_ansi.h>
#include <_syslist.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/times.h>
#include <limits.h>
#include <signal.h>
#include <../Inc/retarget.h>
#include <stdint.h>
#include <stdio.h>
#if !defined(OS_USE_SEMIHOSTING)
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
UART_HandleTypeDef *gHuart;
void RetargetInit(UART_HandleTypeDef *huart) {
gHuart = huart;
/* Disable I/O buffering for STDOUT stream, so that
* chars are sent out as soon as they are printed. */
setvbuf(stdout, NULL, _IONBF, 0);
}
int _isatty(int fd) {
if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)
return 1;
errno = EBADF;
return 0;
}
int _write(int fd, char* ptr, int len) {
HAL_StatusTypeDef hstatus;
if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
hstatus = HAL_UART_Transmit(gHuart, (uint8_t *) ptr, len, HAL_MAX_DELAY);
if (hstatus == HAL_OK)
return len;
else
return EIO;
}
errno = EBADF;
return -1;
}
int _close(int fd) {
if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)
return 0;
errno = EBADF;
return -1;
}
int _lseek(int fd, int ptr, int dir) {
(void) fd;
(void) ptr;
(void) dir;
errno = EBADF;
return -1;
}
int _read(int fd, char* ptr, int len) {
HAL_StatusTypeDef hstatus;
if (fd == STDIN_FILENO) {
hstatus = HAL_UART_Receive(gHuart, (uint8_t *) ptr, 1, HAL_MAX_DELAY);
if (hstatus == HAL_OK)
return 1;
else
return EIO;
}
errno = EBADF;
return -1;
}
int _fstat(int fd, struct stat* st) {
if (fd >= STDIN_FILENO && fd <= STDERR_FILENO) {
st->st_mode = S_IFCHR;
return 0;
}
errno = EBADF;
return 0;
}
#endif //#if !defined(OS_USE_SEMIHOSTING)

18
printf/retarget.h Normal file
View File

@ -0,0 +1,18 @@
// All credit to Carmine Noviello for this code
// https://github.com/cnoviello/mastering-stm32/blob/master/nucleo-f030R8/system/include/retarget/retarget.h
#ifndef _RETARGET_H__
#define _RETARGET_H__
#include "stm32l4xx_hal.h"
#include <sys/stat.h>
void RetargetInit(UART_HandleTypeDef *huart);
int _isatty(int fd);
int _write(int fd, char* ptr, int len);
int _close(int fd);
int _lseek(int fd, int ptr, int dir);
int _read(int fd, char* ptr, int len);
int _fstat(int fd, struct stat* st);
#endif //#ifndef _RETARGET_H__

17
printf/usage.md Normal file
View File

@ -0,0 +1,17 @@
Right-click on the syscalls.c file and select Properties. Under C/C++ Build > Settings, check Exclude resource from build.
in main.c: <br/>
```c
#include <stdio.h>
#include "retarget.h"
char buf[100];
RetargetInit(&huart1);
```
Example:<br/>
```c
printf("\r\nYour name: ");
scanf("%s", buf);
printf("\r\nHello, %s!\r\n", buf);
```