-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
90ae2de
commit 16a3816
Showing
6 changed files
with
333 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# i2c slave based on stm32 | ||
This is an i2c slave based on stm32. This implements a simple math calculator | ||
for doing addition, subtraction and multiplication of given two numbers. | ||
|
||
## how to compile | ||
|
||
Modify `meson.build` according to your needs. | ||
|
||
`libocm3Path` - libopencm3 directory path | ||
|
||
You need to issue `./build.sh` for once. | ||
```shell | ||
$ ./build.sh | ||
$ cd builddir | ||
``` | ||
ninja - generates elf file. | ||
```shell | ||
$ ninja | ||
``` | ||
|
||
ninja hex - generates hex file. | ||
```shell | ||
$ ninja hex | ||
``` | ||
ninja size - gives the summary of hex file size. | ||
```shell | ||
$ ninja size | ||
``` | ||
ninja upload - upload hex file to stm32 via stlink programmer. | ||
```shell | ||
$ ninja upload | ||
``` | ||
|
||
Refer to [my blog](http://amitesh-singh.github.io/stm32/2018/01/07/making-i2c-slave-using-stm32f103.html) for more details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
meson . builddir --cross-file cross-file.txt --buildtype=minsize |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[binaries] | ||
c = 'arm-none-eabi-gcc' | ||
cpp = 'arm-none-eabi-g++' | ||
ar = 'arm-none-eabi-ar' | ||
strip = 'arm-none-eabi-strip' | ||
objcopy = 'arm-none-eabi-objcopy' | ||
size = 'arm-none-eabi-size' | ||
|
||
[host_machine] | ||
system = 'linux' | ||
cpu_family = 'x86_64' | ||
cpu = 'x64' | ||
endian = 'little' | ||
|
||
[target_machine] | ||
system = 'bare-metel' | ||
cpu_family = 'stm32' | ||
cpu = 'STM32F1' | ||
endian = 'little' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
MEMORY | ||
{ | ||
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K | ||
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 20K | ||
} | ||
|
||
INCLUDE libopencm3_stm32f1.ld | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
/* | ||
* math calculator i2c slave stm32 | ||
* Copyright (C) 2017 Amitesh Singh <[email protected]> | ||
* | ||
* 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/>. | ||
*/ | ||
|
||
extern "C" | ||
{ | ||
#include <libopencm3/cm3/common.h> | ||
#include <libopencm3/stm32/rcc.h> | ||
#include <libopencm3/stm32/gpio.h> | ||
#include <libopencm3/stm32/i2c.h> | ||
#include <libopencm3/cm3/nvic.h> | ||
} | ||
|
||
static void | ||
my_delay_1( void ) | ||
{ | ||
int i = 72e6/2/4; | ||
|
||
while( i > 0 ) | ||
{ | ||
i--; | ||
__asm__( "nop" ); | ||
} | ||
} | ||
|
||
#define MYSLAVE_ADDRESS 0x32 | ||
//Set Commands | ||
#define MYSLAVE_SET_REG 0x01 | ||
//GET commands | ||
#define MYSLAVE_GET_ADD_RESULT 0x02 | ||
#define MYSLAVE_GET_SUB_RESULT 0x03 | ||
#define MYSLAVE_GET_MUL_RESULT 0x04 | ||
|
||
static void | ||
i2c_slave_init(uint8_t ownaddress) | ||
{ | ||
rcc_periph_clock_enable(RCC_GPIOB); | ||
rcc_periph_clock_enable(RCC_I2C1); | ||
|
||
nvic_enable_irq(NVIC_I2C1_EV_IRQ); | ||
|
||
// configure i2c pins | ||
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, | ||
GPIO_I2C1_SDA); //PB7 | ||
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, | ||
GPIO_I2C1_SCL); //PB6 | ||
|
||
i2c_reset(I2C1); | ||
i2c_peripheral_disable(I2C1); | ||
|
||
i2c_set_speed(I2C1, i2c_speed_sm_100k, I2C_CR2_FREQ_36MHZ); | ||
i2c_set_own_7bit_slave_address(I2C1, ownaddress); | ||
i2c_enable_interrupt(I2C1, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN); | ||
i2c_peripheral_enable(I2C1); | ||
|
||
// slave needs to acknowledge on receiving bytes | ||
// set it after enabling Peripheral i.e. PE = 1 | ||
i2c_enable_ack(I2C1); | ||
} | ||
|
||
volatile uint8_t *read_p; | ||
volatile uint8_t *write_p; | ||
volatile uint8_t writing; | ||
volatile uint8_t reading; | ||
|
||
volatile uint8_t buf[3]; | ||
volatile uint16_t val; | ||
|
||
//i2c1 event ISR | ||
extern "C" void i2c1_ev_isr(void) | ||
{ | ||
uint32_t sr1, sr2; | ||
|
||
sr1 = I2C_SR1(I2C1); | ||
|
||
if (sr1 & I2C_SR1_ADDR) | ||
{ | ||
reading = 0; | ||
read_p = buf; | ||
write_p = ((volatile uint8_t *)(&val) + 1); | ||
writing = 2; | ||
//Clear the ADDR sequence by reading SR2. | ||
sr2 = I2C_SR2(I2C1); | ||
(void) sr2; | ||
} | ||
else if (sr1 & I2C_SR1_RxNE) | ||
{ | ||
//ignore more than 3 bytes reading | ||
if (reading > 3) | ||
return; | ||
//read bytes from slave | ||
*read_p++ = i2c_get_data(I2C1); | ||
reading++; | ||
} | ||
else if ((sr1 & I2C_SR1_TxE) && !(sr1 & I2C_SR1_BTF)) | ||
{ | ||
//send data to master in MSB order | ||
i2c_send_data(I2C1, *write_p--); | ||
writing--; | ||
} | ||
// done by master by sending STOP | ||
//this event happens when slave is in Recv mode at the end of communication | ||
else if (sr1 & I2C_SR1_STOPF) | ||
{ | ||
i2c_peripheral_enable(I2C1); | ||
|
||
if (buf[0] == MYSLAVE_GET_ADD_RESULT) | ||
val = buf[1] + buf[2]; | ||
else if (buf[0] == MYSLAVE_GET_SUB_RESULT) | ||
val = buf[1] - buf[2]; | ||
else if (buf[0] == MYSLAVE_GET_MUL_RESULT) | ||
val = buf[1] * buf[2]; | ||
} | ||
//this event happens when slave is in transmit mode at the end of communication | ||
else if (sr1 & I2C_SR1_AF) | ||
{ | ||
//(void) I2C_SR1(I2C1); | ||
I2C_SR1(I2C1) &= ~(I2C_SR1_AF); | ||
} | ||
} | ||
|
||
int main( void ) | ||
{ | ||
//set STM32 to 72 MHz | ||
rcc_clock_setup_in_hse_8mhz_out_72mhz(); | ||
|
||
// Enable GPIOC clock | ||
rcc_periph_clock_enable(RCC_GPIOC); | ||
//Set GPIO13 (inbuild led connected) to 'output push-pull' | ||
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, | ||
GPIO13); | ||
//switch led off | ||
gpio_set(GPIOC, GPIO13); | ||
|
||
//initialize i2c slave | ||
i2c_slave_init(MYSLAVE_ADDRESS); | ||
|
||
while( 1 ) | ||
{ | ||
gpio_toggle(GPIOC, GPIO13); | ||
my_delay_1(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# | ||
# stm32-libopencm3-meson build | ||
# Copyright (C) 2017 Amitesh Singh | ||
# | ||
# This library is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU Lesser General Public | ||
# License as published by the Free Software Foundation; either | ||
# version 2.1 of the License, or (at your option) any later version. | ||
# | ||
# This library 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 | ||
# Lesser General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Lesser General Public | ||
# License along with this library; | ||
# if not, see <http://www.gnu.org/licenses/>. | ||
# | ||
|
||
|
||
project('stm32f1-project', 'cpp') | ||
|
||
compiler_obj = meson.get_compiler('cpp') | ||
|
||
size = find_program('arm-none-eabi-size') | ||
objcopy = find_program('arm-none-eabi-objcopy') | ||
stinfo = find_program('st-info') | ||
stflash = find_program('st-flash') | ||
|
||
#define libopencm3 path here | ||
libocm3Path = '/home/ami/repos/libopencm3' | ||
|
||
#define cpu types here | ||
cputype = 'cortex-m3' | ||
cpudefine = 'STM32F1' | ||
libocm3cputype = 'opencm3_stm32f1' | ||
|
||
#Add your source files here | ||
srcfiles = ['main.cpp'] | ||
|
||
|
||
libocm3IncPath = libocm3Path + '/include' | ||
libocm3LibPath = libocm3Path + '/lib' | ||
|
||
# check for libopencm3 library | ||
libocm3lib_obj = compiler_obj.find_library(libocm3cputype, required: true, dirs: libocm3LibPath) | ||
if libocm3lib_obj.found() == true | ||
message('Found libopencm3 library at ' + libocm3Path) | ||
else | ||
error('unable to find libopencm3 library') | ||
endif | ||
|
||
incdir = include_directories(libocm3IncPath) | ||
|
||
stm32f1cargs = ['-Os', | ||
'-ggdb', | ||
'-mcpu=' + cputype, | ||
'-mthumb', | ||
'-msoft-float', | ||
'-std=gnu++14', | ||
'-Wall', | ||
'-Wshadow', | ||
'-ffunction-sections', | ||
'-fdata-sections', | ||
'-D' + cpudefine, | ||
'-fno-exceptions', | ||
#'-I' + libocm3IncPath | ||
] | ||
|
||
stm32f1linkargs = ['-Os', | ||
'-ggdb', | ||
'-D' + cpudefine, | ||
'-fdata-sections', | ||
'-mcpu=' + cputype, | ||
'-mthumb', | ||
'-msoft-float', | ||
'-lc', | ||
'-flto', | ||
#'-T../libopencm3_f1.ld', | ||
'-T' + meson.current_source_dir() + '/libopencm3_f1.ld', | ||
'--specs=nosys.specs', | ||
'-nostartfiles', | ||
'-Wl,--gc-sections', | ||
'-L' + libocm3LibPath, | ||
# '-l' + libocm3cputype, | ||
] | ||
|
||
p = ['blink', srcfiles, stm32f1cargs, stm32f1linkargs] | ||
|
||
exe = executable(p[0], p[1], | ||
cpp_args: p[2], | ||
link_args: p[3], | ||
include_directories : incdir, | ||
dependencies: libocm3lib_obj, | ||
build_by_default: true) | ||
|
||
run_target('hex', command: [objcopy, ['-Obinary', exe.full_path(), | ||
exe.full_path() + '.hex']], depends: exe) | ||
run_target('size', command: [size, exe.full_path(), '-B'], depends: exe) | ||
|
||
# STlink programmer related commands | ||
run_target('probe', command: [stinfo, '--probe']) | ||
run_target('upload', command: [stflash, 'write', exe.full_path() + '.hex', '0x08000000'], depends: exe) | ||
|
||
if meson.is_cross_build() | ||
message('cross compiling for ' + cputype) | ||
message(' \n ninja - generates elf file. | ||
ninja hex - generates hex file. | ||
ninja upload - upload hex file to stm32 via stlink programmer. | ||
ninja probe - probe stlink programmer. | ||
ninja size - gives the summary of hex file size. | ||
(C) Amitesh Singh ') | ||
endif | ||
|