1234
This commit is contained in:
parent
4d4b706a3d
commit
1ed9449d96
16
ADC.c
Normal file
16
ADC.c
Normal 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
452
Alink.c
Normal 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
62
Alink.h
Normal 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
24
GPIO.c
Normal 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;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
# STM32_Examples
|
||||
# STM32 Examples
|
||||
|
||||
Example code for STM32 MCUs
|
||||
Examples for STM32 MCUs
|
60
STM_Flash.c
Normal file
60
STM_Flash.c
Normal 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
17
STM_WatchDog.c
Normal 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
210
Soft_SPI.c
Normal 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
8
Soft_SPI.h
Normal 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
31
TIM.c
Normal 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
43
Trace_debug.md
Normal 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
115
UART.c
Normal 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
94
printf/retarget.c
Normal 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
18
printf/retarget.h
Normal 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
17
printf/usage.md
Normal 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);
|
||||
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user