This commit is contained in:
Andreas Mieke 2018-03-18 23:43:59 +01:00
parent 4093cd295f
commit dc99dcf6e8
41 changed files with 1775 additions and 19 deletions

14
Mieke/SW/ODD/bluetooth.c Normal file
View file

@ -0,0 +1,14 @@
#include "bluetooth.h"
void bluetooth_init(void)
{
usart1_init();
}
void bluetooth_send_gyro_data(uint8_t X, uint8_t Y, uint8_t Z)
{
char __str[128] = {0};
char *str = __str;
sprintf(str, "%d,%d,%d\r\n", X, Y, Z);
USART_SendString(USART1, str);
}

11
Mieke/SW/ODD/bluetooth.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef BLUETOOTH_H
#define BLUETOOTH_H
#include "stm32f10x.h" // Device header
#include "io.h"
#include "stdio.h"
void bluetooth_init(void);
void bluetooth_send_gyro_data(uint8_t X, uint8_t Y, uint8_t Z);
#endif

61
Mieke/SW/ODD/bma.c Normal file
View file

@ -0,0 +1,61 @@
#include "bma.h"
#define BMA_ADDR (uint8_t)0x70 // 0b01110000
// ---- Vendor address part
// --- User address part
// - Keep free for R/W bit (set by I2C_Send7bitAddress())
void bma_init(void)
{
i2c1_init();
}
void bma_get_acc(uint8_t *X, uint8_t *Y, uint8_t *Z)
{
int16_t acc[3];
// Select first register address to read
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, BMA_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, 0x02);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
I2C_GenerateSTART(I2C1, ENABLE);
I2C_AcknowledgeConfig(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, BMA_ADDR, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
// X LSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[0] = (I2C_ReceiveData(I2C1) & 0xC0) >> 6;
// X MSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[0] = (I2C_ReceiveData(I2C1) & 0xFF) << 2 | (acc[0] & 0x0003);
if(acc[0] & 0x0200) acc[0] |= 0xFC00;
// Y LSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[1] = (I2C_ReceiveData(I2C1) & 0xC0) >> 6;
// Y MSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[1] = (I2C_ReceiveData(I2C1) & 0xFF) << 2 | (acc[1] & 0x0003);
if(acc[1] & 0x0200) acc[1] |= 0xFC00;
// Z LSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[2] = (I2C_ReceiveData(I2C1) & 0xC0) >> 6;
// Z MSB
I2C_AcknowledgeConfig(I2C1, DISABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[2] = (I2C_ReceiveData(I2C1) & 0xFF) << 2 | (acc[2] & 0x0003);
if(acc[2] & 0x0200) acc[2] |= 0xFC00;
I2C_GenerateSTOP(I2C1, ENABLE);
*X = (acc[0]/4) + 128;
*Y = (acc[1]/4) + 128;
*Z = (acc[2]/4) + 128;
}

11
Mieke/SW/ODD/bma.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef BMA_H
#define BMA_H
#include "stm32f10x.h" // Device header
#include "io.h"
void bma_init(void);
void bma_get_acc(uint8_t *X, uint8_t *Y, uint8_t *Z);
#endif

59
Mieke/SW/ODD/display.c Normal file
View file

@ -0,0 +1,59 @@
#include "display.h"
disp_state_t state = DISP_STATE_NONE;
uint8_t running = 0;
void USART3_IRQHandler(void)
{
if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET) {
state = (disp_state_t)((USART_ReceiveData(USART3) & 0x00FF) - '0');
if (state > 4) {
state = DISP_STATE_NONE;
}
}
if (state == DISP_STATE_START) {
running = 1;
} else if (state == DISP_STATE_PAUSE) {
running = 0;
}
}
void disp_init(void)
{
usart3_init();
NVIC_InitTypeDef nvic;
nvic.NVIC_IRQChannel = USART3_IRQn;
nvic.NVIC_IRQChannelCmd = ENABLE;
nvic.NVIC_IRQChannelPreemptionPriority = 0;
nvic.NVIC_IRQChannelSubPriority = 2;
NVIC_Init(&nvic);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
disp_disable();
}
disp_state_t disp_get_last_state(void)
{
disp_state_t tmp = state;
state = DISP_STATE_NONE;
return tmp;
}
void disp_send_gyro_data(uint8_t X, uint8_t Y, uint8_t Z)
{
char __str[128] = {0};
char *str = __str;
sprintf(str, "add 1,0,%d\xFF\xFF\xFF" "add 1,1,%d\xFF\xFF\xFF" "add 1,2,%d\xFF\xFF\xFF", X, Y, Z);
USART_SendString(USART3, str);
}
void disp_disable(void)
{
USART_SendString(USART3, "dim=0\xFF\xFF\xFF");
}
void disp_enable(void)
{
USART_SendString(USART3, "dim=100\xFF\xFF\xFF");
}

24
Mieke/SW/ODD/display.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef DISPLAY_H
#define DISPLAY_H
#include "stm32f10x.h" // Device header
#include "io.h"
#include "stdio.h"
typedef enum uint8_t {
DISP_STATE_NONE = 0x00,
DISP_STATE_PAUSE,
DISP_STATE_START,
DISP_STATE_SAVE,
DISP_STATE_RECALL,
DISP_STATE_ERROR = 0xFF - '0'
} disp_state_t;
void disp_init(void);
disp_state_t disp_get_last_state(void);
void disp_send_gyro_data(uint8_t X, uint8_t Y, uint8_t Z);
void disp_disable(void);
void disp_enable(void);
#endif

72
Mieke/SW/ODD/eeprom.c Normal file
View file

@ -0,0 +1,72 @@
#include "eeprom.h"
extern volatile uint32_t SysTickCnt;
#define EEPROM_ADDR (uint8_t)0xA0 // 0b10100000
// ---- Vendor address part
// --- User address part
// - Keep free for R/W bit (set by I2C_Send7bitAddress())
uint32_t last_write_tick = 0;
void eeprom_init(void)
{
i2c1_init();
}
void eeprom_read(uint16_t address, uint8_t *data, uint16_t length)
{
uint16_t cur_pos;
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, (address & 0xFF00) >> 8);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, (address & 0x00FF));
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(I2C1, ENABLE);
I2C_AcknowledgeConfig(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
for(cur_pos = 0; cur_pos < length; cur_pos++) {
if(cur_pos == length - 1) {
I2C_AcknowledgeConfig(I2C1, DISABLE);
}
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
data[cur_pos] = I2C_ReceiveData(I2C1);
}
I2C_GenerateSTOP(I2C1, ENABLE);
}
void eeprom_write(uint16_t address, uint8_t *data, uint16_t length)
{
uint8_t cur_page = 0;
uint16_t cur_pos = 0;
address = address & 0xFFA0;
for(cur_page = 0; cur_page <= ((length-1)/64); cur_page++) {
while((SysTickCnt - last_write_tick) <= 5);
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, (address & 0xFF00) >> 8);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, (address & 0x00FF));
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
for(; (cur_pos < length) && (cur_pos%64 <= 63); cur_pos++) {
I2C_SendData(I2C1, data[cur_pos]);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
I2C_GenerateSTOP(I2C1, ENABLE);
address += 0x0040;
last_write_tick = SysTickCnt;
}
}

13
Mieke/SW/ODD/eeprom.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef EEPROM_H
#define EEPROM_H
#include "stm32f10x.h" // Device header
#include "io.h"
#include "systick.h"
void eeprom_init(void);
void eeprom_read(uint16_t address, uint8_t *data, uint16_t length);
void eeprom_write(uint16_t address, uint8_t *data, uint16_t length);
#endif

111
Mieke/SW/ODD/io.c Normal file
View file

@ -0,0 +1,111 @@
#include "io.h"
uint8_t i2c1_inited = 0;
uint8_t usart1_inited = 0;
uint8_t usart3_inited = 0;
void i2c1_init(void)
{
if (i2c1_inited == 1) {
return;
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
// SCL
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &gpio);
// SDA
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
gpio.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &gpio);
I2C_InitTypeDef i2c;
I2C_StructInit(&i2c);
i2c.I2C_ClockSpeed = 400000;
I2C_Init(I2C1, &i2c);
I2C_Cmd(I2C1, ENABLE);
i2c1_inited = 1;
}
void usart1_init(void)
{
if (usart1_inited == 1) {
return;
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
// TxD
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOA, &gpio);
// RxD
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &gpio);
USART_InitTypeDef usart;
USART_StructInit(&usart);
usart.USART_BaudRate = 115200;
USART_Init(USART1, &usart);
USART_ClockInitTypeDef usartclock;
USART_ClockStructInit(&usartclock);
USART_ClockInit(USART1, &usartclock);
USART_Cmd(USART1, ENABLE);
usart1_inited = 1;
}
void usart3_init(void)
{
if (usart3_inited == 1) {
return;
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
// TxD
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOB, &gpio);
// RxD
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio.GPIO_Pin = GPIO_Pin_11;
GPIO_Init(GPIOB, &gpio);
USART_InitTypeDef usart;
USART_StructInit(&usart);
usart.USART_BaudRate = 115200;
USART_Init(USART3, &usart);
USART_ClockInitTypeDef usartclock;
USART_ClockStructInit(&usartclock);
USART_ClockInit(USART3, &usartclock);
USART_Cmd(USART3, ENABLE);
usart3_inited = 1;
}
void USART_SendString(USART_TypeDef *USARTx, char *str)
{
while (*str) {
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
USART_SendData(USARTx, *str++);
}
}

16
Mieke/SW/ODD/io.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef IO_H
#define IO_H
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC
#include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO
#include "stm32f10x_usart.h" // Keil::Device:StdPeriph Drivers:USART
#include "stm32f10x_i2c.h" // Keil::Device:StdPeriph Drivers:I2C
void i2c1_init(void);
void usart1_init(void);
void usart3_init(void);
void USART_SendString(USART_TypeDef *USARTx, char *str);
#endif

56
Mieke/SW/ODD/main.c Normal file
View file

@ -0,0 +1,56 @@
#include "display.h"
#include "bma.h"
#include "eeprom.h"
#include "bluetooth.h"
#define BUFFER_SIZE 256
int main()
{
disp_state_t current_state = DISP_STATE_NONE;
uint8_t X, Y, Z, running = 0;
uint8_t bX[BUFFER_SIZE] = {128}, bY[BUFFER_SIZE] = {128}, bZ[BUFFER_SIZE] = {128};
uint16_t buffer_pos = 0;
disp_init();
systick_init();
bma_init();
eeprom_init();
bluetooth_init();
disp_enable();
// Main loop
for (;;) {
current_state = disp_get_last_state();
if(current_state == DISP_STATE_START) {
running = 1;
} else if(current_state == DISP_STATE_PAUSE) {
running = 0;
}
if(running == 1) {
bma_get_acc(&X, &Y, &Z);
bX[buffer_pos] = X;
bY[buffer_pos] = Y;
bZ[buffer_pos] = Z;
disp_send_gyro_data(X, Y, Z);
bluetooth_send_gyro_data(X, Y, Z);
buffer_pos++;
if(buffer_pos == BUFFER_SIZE) {
buffer_pos = 0;
}
}
if(current_state == DISP_STATE_SAVE) {
eeprom_write(0x0000, bX, BUFFER_SIZE);
eeprom_write(0x0400, bY, BUFFER_SIZE);
eeprom_write(0x0800, bZ, BUFFER_SIZE);
}
if(current_state == DISP_STATE_RECALL) {
eeprom_read(0x0000, bX, BUFFER_SIZE);
eeprom_read(0x0400, bY, BUFFER_SIZE);
eeprom_read(0x0800, bZ, BUFFER_SIZE);
for(uint16_t i = 0; i < BUFFER_SIZE; i++) {
disp_send_gyro_data(bX[i], bY[i], bZ[i]);
bluetooth_send_gyro_data(bX[i], bY[i], bZ[i]);
}
}
}
}

23
Mieke/SW/ODD/systick.c Normal file
View file

@ -0,0 +1,23 @@
#include "systick.h"
volatile uint32_t SysTickCnt;
void SysTick_Handler()
{
SysTickCnt++;
}
void systick_init(void)
{
RCC_ClocksTypeDef clocks;
RCC_GetClocksFreq(&clocks);
SysTick_Config(clocks.HCLK_Frequency/1000 - 1);
SysTickCnt = 0;
}
void Wait(uint32_t ms)
{
uint32_t SysTickCntHold = SysTickCnt;
while((SysTickCnt - SysTickCntHold) <= ms);
}

12
Mieke/SW/ODD/systick.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef SYSTICK_H
#define SYSTICK_H
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC
extern volatile uint32_t SysTickCnt;
void systick_init(void);
void Wait(uint32_t ms);
#endif