add I2C to F1_testbrd

This commit is contained in:
Edward Emelianov 2023-01-04 21:10:31 +03:00
parent 282bed0d8f
commit cc25da3d12
22 changed files with 589 additions and 186 deletions

View File

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 8.0.2, 2022-12-29T21:48:22. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{7bd84e39-ca37-46d3-be9d-99ebea85bc0d}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">KOI8-R</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">false</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
<value type="bool" key="AutoTest.Framework.Boost">true</value>
<value type="bool" key="AutoTest.Framework.CTest">false</value>
<value type="bool" key="AutoTest.Framework.Catch">true</value>
<value type="bool" key="AutoTest.Framework.GTest">true</value>
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
</valuemap>
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
<value type="int" key="AutoTest.RunAfterBuild">0</value>
<value type="bool" key="AutoTest.UseGlobal">true</value>
<valuemap type="QVariantMap" key="ClangTools">
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">2</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
</valuemap>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{65a14f9e-e008-4c1b-89df-4eaa4774b6e3}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Big/Data/00__Electronics/STM32/F1-nolib/F1_testbrd</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Очистка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Очистка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Развёртывание</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Развёртывание</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

View File

@ -3,6 +3,8 @@ adc.c
adc.h
hardware.c
hardware.h
i2c.c
i2c.h
main.c
pl2303.bin
proto.c

View File

@ -10,7 +10,7 @@ DENSITY ?= LD
# change this linking script depending on particular MCU model,
LDSCRIPT ?= stm32f103x6.ld
# debug
#DEFS = -DEBUG
DEFS = -DEBUG
INDEPENDENT_HEADERS=

View File

@ -1 +1,6 @@
Simple test for STM32F103, blinking PA0/PA1, two user buttons (PA14 and PA15) and USB (PL2303 emulator) <> USART1 echo.
Simple test for STM32F103:
USART1
I2C1
USB
5 PWM channels
ADC1.0 & ADC1.5

View File

@ -1,6 +1,6 @@
/*
* This file is part of the Chiller project.
* Copyright 2018 Edward V. Emelianov <edward.emelianoff@gmail.com>.
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/*
* This file is part of the Chiller project.
* Copyright 2018 Edward V. Emelianov <edward.emelianoff@gmail.com>.
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,9 +15,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ADC_H
#define ADC_H
#include "stm32f1.h"
#include <stm32f1.h>
#define NUMBER_OF_ADC_CHANNELS (5)
@ -40,4 +39,3 @@ uint32_t getVdd();
uint16_t getADCval(int nch);
uint32_t getADCvoltage(int nch);
#endif // ADC_H

View File

@ -1,12 +1,10 @@
/*
* geany_encoding=koi8-r
* hardware.c - hardware-dependent macros & functions
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
@ -15,10 +13,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "adc.h"

View File

@ -1,12 +1,10 @@
/*
* geany_encoding=koi8-r
* hardware.h
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
@ -15,35 +13,12 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __HARDWARE_H__
#define __HARDWARE_H__
#include <stm32f1.h>
#if 0
#ifndef CONCAT
#define CONCAT(a,b) a ## b
#endif
#ifndef STR_HELPER
#define STR_HELPER(s) #s
#endif
#ifndef STR
#define STR(s) STR_HELPER(s)
#endif
// PWM LEDS
#define SET_LED_PWM3(ch, N) do{TIM3->CCR ## ch = (uint32_t)N;}while(0)
#define GET_LED_PWM3(ch) (uint8_t)(TIM3->CCR ## ch)
#define SET_LED_PWM1(N) do{TIM1->CCR1 = (uint32_t)N;}while(0)
#define GET_LED_PWM1() (uint8_t)(TIM1->CCR1)
#endif
// USB pullup (not used in STM32F0x2!) - PA13
#define USBPU_port GPIOA
#define USBPU_pin (1<<15)
@ -52,4 +27,3 @@
void hw_setup();
#endif // __HARDWARE_H__

272
F1:F103/F1_testbrd/i2c.c Normal file
View File

@ -0,0 +1,272 @@
/*
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "hardware.h"
#include "i2c.h"
#include "proto.h"
#include "usart.h"
#include "usb.h"
I2C_SPEED curI2Cspeed = LOW_SPEED;
extern volatile uint32_t Tms;
volatile uint8_t I2C_scan_mode = 0; // == 1 when I2C is in scan mode
static uint8_t i2caddr = I2C_ADDREND; // current address for scan mode (not active)
static uint8_t addr7r = 0, addr7w = 0;
void i2c_set_addr7(uint8_t addr){
#ifdef EBUG
usart_send("Change I2C address to ");
usart_send(uhex2str(addr));
usart_putchar('\n');
#endif
addr7w = addr << 1;
addr7r = addr7w | 1;
}
/*
* GPIO Resources: I2C1_SCL - PB6, I2C1_SDA - PB7
*/
void i2c_setup(I2C_SPEED speed){
if(speed >= CURRENT_SPEED){
speed = curI2Cspeed;
}else{
curI2Cspeed = speed;
}
I2C1->CR1 = 0;
I2C1->SR1 = 0;
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
GPIOB->CRL = (GPIOB->CRL & ~(GPIO_CRL_CNF6 | GPIO_CRL_CNF7)) |
CRL(6, CNF_AFOD | MODE_NORMAL) | CRL(7, CNF_AFOD | MODE_NORMAL);
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
I2C1->CR2 = 8; // FREQR=8MHz, T=125ns
I2C1->TRISE = 9; // (9-1)*125 = 1mks
if(speed == LOW_SPEED){ // 10kHz
I2C1->CCR = 400;
}else if(speed == HIGH_SPEED){ // 100kHz
I2C1->CCR = 40; // normal mode, 8MHz/2/40 = 100kHz
}else{ // VERYLOW_SPEED - 976.8Hz
I2C1->CCR = 0xfff;
}
I2C1->CR1 = I2C_CR1_PE;
}
// wait for event evt no more than 2 ms
#define I2C_WAIT(evt) do{ register uint32_t wait4 = Tms + 2; \
while(Tms < wait4 && !(evt)) IWDG->KR = IWDG_REFRESH; \
if(!(evt)){DBG("WAIT!\n"); return FALSE;}}while(0)
// wait for !busy
#define I2C_LINEWAIT() do{ register uint32_t wait4 = Tms + 2; \
while(Tms < wait4 && (I2C1->SR2 & I2C_SR2_BUSY)) IWDG->KR = IWDG_REFRESH; \
if(I2C1->SR2 & I2C_SR2_BUSY){I2C1->CR1 |= I2C_CR1_SWRST; DBG("LINE!\n"); return FALSE;}\
}while(0)
// start writing, return FALSE @ error
static int i2c_7bit_startw(){
if(I2C1->CR1 != I2C_CR1_PE) i2c_setup(CURRENT_SPEED);
if(I2C1->SR1) I2C1->SR1 = 0; // clear NACK and other problems
(void) I2C1->SR2;
I2C_LINEWAIT();
DBG("linew\n");
I2C1->CR1 |= I2C_CR1_START; // generate start sequence
I2C_WAIT(I2C1->SR1 & I2C_SR1_SB); // wait for SB
DBG("SB\n");
(void) I2C1->SR1; // clear SB
I2C1->DR = addr7w; // set address
I2C_WAIT(I2C1->SR1 & I2C_SR1_ADDR); // wait for ADDR flag (timeout @ NACK)
DBG("ADDR\n");
if(I2C1->SR1 & I2C_SR1_AF){ // NACK
return FALSE;
}
DBG("ACK\n");
(void) I2C1->SR2; // clear ADDR
return TRUE;
}
/**
* send one byte in 7bit address mode
* @param data - data to write
* @param stop - ==1 to send stop event
* @return TRUE if OK
*
static int i2c_7bit_send_onebyte(uint8_t data, uint8_t stop){
int ret = i2c_7bit_startw();
if(!ret){
I2C1->CR1 |= I2C_CR1_STOP;
return FALSE;
}
I2C1->DR = data; // init data send register
DBG("TxE\n");
I2C_WAIT(I2C1->SR1 & I2C_SR1_TXE); // wait for TxE (timeout when NACK)
DBG("OK\n");
if(stop){
I2C_WAIT(I2C1->SR1 & I2C_SR1_BTF); // wait for BTF
DBG("BTF\n");
}
if(stop){
I2C1->CR1 |= I2C_CR1_STOP; // generate stop event
}else{ DBG("No STOP\n");}
return TRUE;
}*/
int i2c_7bit_receive_onebyte(uint8_t *data, uint8_t stop){
I2C1->CR1 |= I2C_CR1_START; // generate start sequence
I2C_WAIT(I2C1->SR1 & I2C_SR1_SB); // wait for SB
DBG("got SB\n");
(void) I2C1->SR1; // clear SB
I2C1->DR = addr7r; // set address
DBG("Rx addr\n");
I2C_WAIT(I2C1->SR1 & I2C_SR1_ADDR); // wait for ADDR flag
DBG("Rx ack\n");
I2C1->CR1 &= ~I2C_CR1_ACK; // clear ACK
if(I2C1->SR1 & I2C_SR1_AF){ // NACK
DBG("Rx nak\n");
return FALSE;
}
(void) I2C1->SR2; // clear ADDR
DBG("Rx stop\n");
if(stop) I2C1->CR1 |= I2C_CR1_STOP; // program STOP
I2C_WAIT(I2C1->SR1 & I2C_SR1_RXNE); // wait for RxNE
DBG("Rx OK\n");
*data = I2C1->DR; // read data & clear RxNE
return TRUE;
}
int i2c_7bit_receive_twobytes(uint8_t *data){
I2C1->CR1 |= I2C_CR1_START | I2C_CR1_POS | I2C_CR1_ACK; // generate start sequence, set pos & ack
I2C_WAIT(I2C1->SR1 & I2C_SR1_SB); // wait for SB
DBG("2 got sb\n");
(void) I2C1->SR1; // clear SB
I2C1->DR = addr7r; // set address
I2C_WAIT(I2C1->SR1 & I2C_SR1_ADDR); // wait for ADDR flag
DBG("2 ADDR\n");
if(I2C1->SR1 & I2C_SR1_AF){ // NACK
return FALSE;
}
DBG("2 ACK\n");
(void) I2C1->SR2; // clear ADDR
I2C1->CR1 &= ~I2C_CR1_ACK; // clear ACK
I2C_WAIT(I2C1->SR1 & I2C_SR1_BTF); // wait for BTF
DBG("2 BTF\n");
I2C1->CR1 |= I2C_CR1_STOP; // program STOP
*data++ = I2C1->DR; *data = I2C1->DR; // read data & clear RxNE
return TRUE;
}
/**
* write command byte to I2C
* @param data - bytes to write
* @param nbytes - amount of bytes to write
* @param stop - to set STOP
* @return 0 if error
*/
static uint8_t write_i2cs(uint8_t *data, uint8_t nbytes, uint8_t stop){
int ret = i2c_7bit_startw();
if(!ret){
DBG("NACK!\n");
I2C1->CR1 |= I2C_CR1_STOP;
return FALSE;
}
for(int i = 0; i < nbytes; ++i){
I2C1->DR = data[i];
I2C_WAIT(I2C1->SR1 & I2C_SR1_TXE);
}
DBG("GOOD\n");
if(nbytes) I2C_WAIT(I2C1->SR1 & I2C_SR1_BTF);
if(stop) I2C1->CR1 |= I2C_CR1_STOP;
return TRUE;
}
uint8_t write_i2c(uint8_t *data, uint8_t nbytes){
return write_i2cs(data, nbytes, 1);
}
/**
* read nbytes of data from I2C line
* `data` should be an array with at least `nbytes` length
* @return 1 if all OK, 0 if NACK or no device found
*/
static uint8_t read_i2cb(uint8_t *data, uint8_t nbytes, uint8_t wait){
if(wait) I2C_LINEWAIT();
I2C1->SR1 = 0; // clear previous NACK flag & other error flags
if(nbytes == 1) return i2c_7bit_receive_onebyte(data, 1);
else if(nbytes == 2) return i2c_7bit_receive_twobytes(data);
I2C1->CR1 |= I2C_CR1_START | I2C_CR1_ACK; // generate start sequence, set pos & ack
I2C_WAIT(I2C1->SR1 & I2C_SR1_SB); // wait for SB
DBG("n got SB\n");
(void) I2C1->SR1; // clear SB
I2C1->DR = addr7r; // set address
I2C_WAIT(I2C1->SR1 & I2C_SR1_ADDR); // wait for ADDR flag
DBG("n send addr\n");
if(I2C1->SR1 & I2C_SR1_AF){ // NACK
DBG("n NACKed\n");
return FALSE;
}
DBG("n ACKed\n");
(void) I2C1->SR2; // clear ADDR
for(uint16_t x = nbytes - 3; x > 0; --x){
I2C_WAIT(I2C1->SR1 & I2C_SR1_RXNE); // wait next byte
*data++ = I2C1->DR; // get data
}
DBG("n three left\n");
// three bytes remain to be read
I2C_WAIT(I2C1->SR1 & I2C_SR1_RXNE); // wait dataN-2
DBG("n dataN-2\n");
I2C_WAIT(I2C1->SR1 & I2C_SR1_BTF); // wait for BTF
DBG("n BTF\n");
I2C1->CR1 &= ~I2C_CR1_ACK; // clear ACK
*data++ = I2C1->DR; // read dataN-2
I2C1->CR1 |= I2C_CR1_STOP; // program STOP
*data++ = I2C1->DR; // read dataN-1
I2C_WAIT(I2C1->SR1 & I2C_SR1_RXNE); // wait next byte
*data = I2C1->DR; // read dataN
DBG("n got it\n");
return TRUE;
}
uint8_t read_i2c(uint8_t *data, uint8_t nbytes){
return read_i2cb(data, nbytes, 1);
}
// read register reg
uint8_t read_i2c_reg(uint8_t reg, uint8_t *data, uint8_t nbytes){
if(nbytes == 0) return write_i2cs(&reg, 1, 1);
DBG("wrote address, now read data\n");
if(!write_i2cs(&reg, 1, 0)) return FALSE;
return read_i2cb(data, nbytes, 0);
}
void i2c_init_scan_mode(){
i2caddr = 0;
I2C_scan_mode = 1;
}
// return 1 if next addr is active & return in as `addr`
// if addresses are over, return 1 and set addr to I2C_NOADDR
// if scan mode inactive, return 0 and set addr to I2C_NOADDR
int i2c_scan_next_addr(uint8_t *addr){
*addr = i2caddr;
if(i2caddr == I2C_ADDREND){
*addr = I2C_ADDREND;
I2C_scan_mode = 0;
return 0;
}
i2c_set_addr7(i2caddr++);
if(!read_i2c_reg(0, NULL, 0)) return FALSE;
return TRUE;
}

45
F1:F103/F1_testbrd/i2c.h Normal file
View File

@ -0,0 +1,45 @@
/*
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stm32f1.h>
#define I2C_ADDREND (0x80)
typedef enum{
VERYLOW_SPEED,
LOW_SPEED,
HIGH_SPEED,
CURRENT_SPEED
} I2C_SPEED;
extern I2C_SPEED curI2Cspeed;
extern volatile uint8_t I2C_scan_mode;
// timeout of I2C bus in ms
#define I2C_TIMEOUT (100)
void i2c_setup(I2C_SPEED speed);
void i2c_set_addr7(uint8_t addr);
uint8_t read_i2c(uint8_t *data, uint8_t nbytes);
uint8_t read_i2c_reg(uint8_t reg, uint8_t *data, uint8_t nbytes);
uint8_t write_i2c(uint8_t *data, uint8_t nbytes);
void i2c_init_scan_mode();
int i2c_scan_next_addr(uint8_t *addr);

View File

@ -1,11 +1,10 @@
/*
* main.c
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* Copyright 2017 Edward V. Emelianoff <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
@ -14,13 +13,12 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "adc.h"
#include "hardware.h"
#include "i2c.h"
#include "proto.h"
#include "usart.h"
#include "usb.h"
@ -47,8 +45,13 @@ int main(void){
usart_setup();
SysTick_Config(72000);
SEND("Hello! I'm ready.\n");
USBPU_OFF();
USB_setup();
USBPU_ON();
i2c_setup(LOW_SPEED);
SEND("Hello! I'm ready.\n");
if(RCC->CSR & RCC_CSR_IWDGRSTF){ // watchdog reset occured
SEND("WDGRESET=1\n");
}
@ -57,10 +60,6 @@ int main(void){
}
RCC->CSR |= RCC_CSR_RMVF; // remove reset flags
USBPU_OFF();
USB_setup();
USBPU_ON();
while (1){
IWDG->KR = IWDG_REFRESH; // refresh watchdog
if(lastT > Tms || Tms - lastT > 499){
@ -81,7 +80,6 @@ int main(void){
lastT = Tms;
transmit_tbuf(); // non-blocking transmission of data from UART buffer every 0.5s
}
/*
if(I2C_scan_mode){
uint8_t addr;
int ok = i2c_scan_next_addr(&addr);
@ -92,7 +90,6 @@ int main(void){
USND(") - found device\n");
}
}
*/
usb_proc();
int r = 0;
char *txt, *ans;

Binary file not shown.

View File

@ -1,6 +1,6 @@
/*
* This file is part of the F0testbrd project.
* Copyright 2021 Edward V. Emelianov <edward.emelianoff@gmail.com>.
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -17,7 +17,7 @@
*/
#include "adc.h"
//#include "i2c.h"
#include "i2c.h"
#include "hardware.h"
#include "proto.h"
//#include "spi.h"
@ -121,21 +121,20 @@ static void hexdump(uint8_t *arr, uint16_t len){
}
}
static uint8_t i2cinited = 0;
static uint8_t i2cinited = 1;
static inline char *setupI2C(char *buf){
buf = omit_spaces(buf);
if(*buf < '0' || *buf > '2') return "Wrong speed";
//i2c_setup(*buf - '0');
i2c_setup(*buf - '0');
i2cinited = 1;
return "OK";
}
static uint8_t I2Caddress = 0;
static inline char *saI2C(char *buf){
uint32_t addr;
if(!getnum(buf, &addr) || addr > 0x7f) return "Wrong address";
I2Caddress = (uint8_t) addr << 1;
USND("I2Caddr="); USB_sendstr(uhex2str(addr)); USND("\n");
i2c_set_addr7(addr);
return "OK";
}
static inline void rdI2C(char *buf){
@ -151,30 +150,22 @@ static inline void rdI2C(char *buf){
if(!nxt || buf == nxt || N > LOCBUFFSZ){
USND("Bad length\n");
return;
}/*
if(!read_i2c_reg(I2Caddress, reg, locBuffer, N)){
}
if(!read_i2c_reg(reg, locBuffer, N)){
USND("Error reading I2C\n");
return;
}*/
}
if(N == 0){ USND("OK"); return; }
USND("Register "); USB_sendstr(uhex2str(reg)); USND(":\n");
hexdump(locBuffer, N);
}
static inline char *wrI2C(char *buf){
uint16_t N = readNnumbers(buf);
//if(!write_i2c(I2Caddress, locBuffer, N)) return "Error writing I2C";
if(!write_i2c(locBuffer, N)) return "Error writing I2C";
if(N < 1) return "bad";
return "OK";
}
static inline char *DAC_chval(char *buf){
uint32_t D;
char *nxt = getnum(buf, &D);
if(!nxt || nxt == buf || D > 4095) return "Wrong DAC amplitude\n";
DAC->DHR12R1 = D;
return "OK";
}
// write locBuffer to SPI
static inline void wrSPI(int SPIidx, char *buf){
if(SPIidx < 0 || SPIidx > 2) return;
@ -223,7 +214,7 @@ const char *helpstring =
"A - get ADC values\n"
"dx - change DAC lowcal to x\n"
"g - get PWM values\n"
"i0..3 - setup I2C with lowest..highest speed (5.8, 10 and 100kHz)\n"
"i0..2 - setup I2C with lowest..highest speed (5.8, 10 and 100kHz)\n"
"Ia addr - set I2C address\n"
"Iw bytes - send bytes (hex/dec/oct/bin) to I2C\n"
"Ir reg n - read n bytes from I2C reg\n"
@ -268,21 +259,18 @@ const char *parse_cmd(char *buf){
return TIM3pwm(buf);
break;
case 'd':
return DAC_chval(buf + 1);
return "DAC not supported @ F103";
case 'i':
return setupI2C(buf + 1);
break;
case 'I':
return "TODO";
/*
if(!i2cinited) return "Init I2C first";
buf = omit_spaces(buf + 1);
if(*buf == 'a') return saI2C(buf + 1);
else if(*buf == 'r'){ rdI2C(buf + 1); return NULL; }
else if(*buf == 'w') return wrI2C(buf + 1);
else if(*buf == 's') i2c_init_scan_mode();
else if(*buf == 's'){ i2c_init_scan_mode(); return "Start scan\n";}
else return "Command should be 'Ia', 'Iw', 'Ir' or 'Is'\n";
*/
break;
case 'p':
case 'P':
@ -320,7 +308,7 @@ const char *parse_cmd(char *buf){
break;
case 'R':
USND("Soft reset\n");
//SEND("Soft reset\n");
SEND("Soft reset\n");
NVIC_SystemReset();
break;
case 'S':
@ -345,7 +333,7 @@ const char *parse_cmd(char *buf){
break;
case 'W':
USND("Wait for reboot\n");
//SEND("Wait for reboot\n");
SEND("Wait for reboot\n");
while(1){nop();};
break;
default: // help

View File

@ -1,6 +1,6 @@
/*
* This file is part of the F0testbrd project.
* Copyright 2021 Edward V. Emelianov <edward.emelianoff@gmail.com>.
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,10 +15,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef PROTO_H__
#define PROTO_H__
#pragma once
#include <stm32f1.h>
extern volatile uint8_t ADCmon;
@ -35,4 +33,3 @@ char *uhex2str(uint32_t val);
char *getnum(const char *txt, uint32_t *N);
char *omit_spaces(const char *buf);
#endif // PROTO_H__

Binary file not shown.

View File

@ -1,11 +1,10 @@
/*
* usart.c
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* Copyright 2018 Edward V. Emelianoff <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
@ -14,11 +13,10 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stm32f1.h"
#include <stm32f1.h>
#include "usart.h"
#include "usb.h"

View File

@ -1,11 +1,10 @@
/*
* usart.h
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* Copyright 2017 Edward V. Emelianoff <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
@ -14,14 +13,10 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __USART_H__
#define __USART_H__
#pragma once
#include <stdint.h>
// input and output buffers size
@ -58,4 +53,3 @@ void usart_send(const char *str);
void newline();
void usart_putchar(const char ch);
#endif // __USART_H__

View File

@ -1,12 +1,10 @@
/*
* geany_encoding=koi8-r
* usb.c - base functions for different USB types
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
@ -15,15 +13,18 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "usart.h"
#include "usb.h"
#include "usb_lib.h"
#ifdef DBG
#undef DBG
#define DBG(x)
#endif
static volatile uint8_t tx_succesfull = 1;
static volatile uint8_t rxNE = 0;

View File

@ -1,12 +1,10 @@
/*
* geany_encoding=koi8-r
* usb.h
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
@ -15,15 +13,10 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __USB_H__
#define __USB_H__
#pragma once
#include "hardware.h"
#define BUFFSIZE (64)
@ -35,5 +28,3 @@ void usb_proc();
void USB_send(const uint8_t *buf, uint16_t len);
void USB_send_blk(const uint8_t *buf, uint16_t len);
uint8_t USB_receive(uint8_t *buf);
#endif // __USB_H__

View File

@ -1,12 +1,10 @@
/*
* geany_encoding=koi8-r
* usb_defs.h
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
@ -15,16 +13,10 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __USB_DEFS_H__
#define __USB_DEFS_H__
#include <stm32f1.h>
// max endpoints number
@ -103,5 +95,3 @@ typedef struct{
typedef struct{
__IO USB_EPDATA_TypeDef EP[STM32ENDPOINTS];
} USB_BtableDef;
#endif // __USB_DEFS_H__

View File

@ -1,12 +1,10 @@
/*
* geany_encoding=koi8-r
* usb_lib.c
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
@ -15,10 +13,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>

View File

@ -1,12 +1,10 @@
/*
* geany_encoding=koi8-r
* usb_lib.h
* This file is part of the F1_testbrd project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
@ -15,16 +13,10 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __USB_LIB_H__
#define __USB_LIB_H__
#include <wchar.h>
#include "usb_defs.h"
@ -185,5 +177,3 @@ void linecoding_handler(usb_LineCoding *lc);
void clstate_handler(uint16_t val);
void break_handler();
void vendor_handler(config_pack_t *packet);
#endif // __USB_LIB_H__