mirror of
https://github.com/EranMorkon/AMTS.git
synced 2023-12-28 16:48:38 +00:00
Comments to source code
This commit is contained in:
parent
d109bae8d7
commit
9a18bd88f0
22 changed files with 286 additions and 122 deletions
|
@ -2,6 +2,7 @@
|
|||
|
||||
void bluetooth_init(void)
|
||||
{
|
||||
// Init USART1
|
||||
usart1_init();
|
||||
}
|
||||
|
||||
|
@ -9,6 +10,8 @@ void bluetooth_send_gyro_data(uint8_t X, uint8_t Y, uint8_t Z)
|
|||
{
|
||||
char __str[128] = {0};
|
||||
char *str = __str;
|
||||
// Print data comma-sperated to String
|
||||
sprintf(str, "%d,%d,%d\r\n", X, Y, Z);
|
||||
// Send string over USARt to the bluetooth module
|
||||
USART_SendString(USART1, str);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#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())
|
||||
// ---- Vendor address part
|
||||
// --- User address part
|
||||
// - Keep free for R/W bit (set by I2C_Send7bitAddress())
|
||||
|
||||
void bma_init(void)
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ void bma_init(void)
|
|||
void bma_get_acc(uint8_t *X, uint8_t *Y, uint8_t *Z)
|
||||
{
|
||||
int16_t acc[3];
|
||||
// Select first register address to read
|
||||
// Send 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);
|
||||
|
@ -22,39 +22,42 @@ void bma_get_acc(uint8_t *X, uint8_t *Y, uint8_t *Z)
|
|||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
|
||||
I2C_GenerateSTOP(I2C1, ENABLE);
|
||||
|
||||
// Start Rx transmission
|
||||
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
|
||||
// Read X LSB
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
|
||||
acc[0] = (I2C_ReceiveData(I2C1) & 0xC0) >> 6;
|
||||
// X MSB
|
||||
// Read 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
|
||||
// Read Y LSB
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
|
||||
acc[1] = (I2C_ReceiveData(I2C1) & 0xC0) >> 6;
|
||||
// Y MSB
|
||||
// Read 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
|
||||
// Read Z LSB
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
|
||||
acc[2] = (I2C_ReceiveData(I2C1) & 0xC0) >> 6;
|
||||
// Z MSB
|
||||
// Read 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;
|
||||
|
||||
// Stop condition
|
||||
I2C_GenerateSTOP(I2C1, ENABLE);
|
||||
|
||||
// Calculate display values, with a maximum amplitude of 2.0g, as described in the datasheet
|
||||
*X = (acc[0]/4) + 128;
|
||||
*Y = (acc[1]/4) + 128;
|
||||
*Z = (acc[2]/4) + 128;
|
||||
|
|
|
@ -5,12 +5,15 @@ uint8_t running = 0;
|
|||
|
||||
void USART3_IRQHandler(void)
|
||||
{
|
||||
// HAndle only USART3 RXNE interrupt
|
||||
if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET) {
|
||||
// Get display state
|
||||
state = (disp_state_t)((USART_ReceiveData(USART3) & 0x00FF) - '0');
|
||||
if (state > 4) {
|
||||
state = DISP_STATE_NONE;
|
||||
}
|
||||
}
|
||||
// Set running according to pressed button
|
||||
if (state == DISP_STATE_START) {
|
||||
running = 1;
|
||||
} else if (state == DISP_STATE_PAUSE) {
|
||||
|
@ -20,8 +23,10 @@ void USART3_IRQHandler(void)
|
|||
|
||||
void disp_init(void)
|
||||
{
|
||||
// Init USART3
|
||||
usart3_init();
|
||||
|
||||
// Init USART3 interrupt
|
||||
NVIC_InitTypeDef nvic;
|
||||
nvic.NVIC_IRQChannel = USART3_IRQn;
|
||||
nvic.NVIC_IRQChannelCmd = ENABLE;
|
||||
|
@ -30,11 +35,13 @@ void disp_init(void)
|
|||
NVIC_Init(&nvic);
|
||||
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
|
||||
|
||||
// Disable display till startup is complete
|
||||
disp_disable();
|
||||
}
|
||||
|
||||
disp_state_t disp_get_last_state(void)
|
||||
{
|
||||
// Returns the last state (which we got form the interrupt)
|
||||
disp_state_t tmp = state;
|
||||
state = DISP_STATE_NONE;
|
||||
return tmp;
|
||||
|
@ -44,16 +51,19 @@ void disp_send_gyro_data(uint8_t X, uint8_t Y, uint8_t Z)
|
|||
{
|
||||
char __str[128] = {0};
|
||||
char *str = __str;
|
||||
// Print gyro data to the display
|
||||
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)
|
||||
{
|
||||
// Disable (dim to 0%) display
|
||||
USART_SendString(USART3, "dim=0\xFF\xFF\xFF");
|
||||
}
|
||||
|
||||
void disp_enable(void)
|
||||
{
|
||||
// Enable display again (dim to 100%)
|
||||
USART_SendString(USART3, "dim=100\xFF\xFF\xFF");
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "io.h"
|
||||
#include "stdio.h"
|
||||
|
||||
// Display states/buttons
|
||||
typedef enum uint8_t {
|
||||
DISP_STATE_NONE = 0x00,
|
||||
DISP_STATE_PAUSE,
|
||||
|
|
|
@ -2,21 +2,24 @@
|
|||
|
||||
extern volatile uint32_t SysTickCnt;
|
||||
|
||||
// EEPROM addresse
|
||||
#define EEPROM_ADDR (uint8_t)0xA0 // 0b10100000
|
||||
// ---- Vendor address part
|
||||
// --- User address part
|
||||
// - Keep free for R/W bit (set by I2C_Send7bitAddress())
|
||||
// ---- 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)
|
||||
{
|
||||
// Init I2C1
|
||||
i2c1_init();
|
||||
}
|
||||
|
||||
void eeprom_read(uint16_t address, uint8_t *data, uint16_t length)
|
||||
{
|
||||
uint16_t cur_pos;
|
||||
// Send address of EEPROM and start address on EEPROM
|
||||
I2C_GenerateSTART(I2C1, ENABLE);
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
|
||||
I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
|
||||
|
@ -26,12 +29,14 @@ void eeprom_read(uint16_t address, uint8_t *data, uint16_t length)
|
|||
I2C_SendData(I2C1, (address & 0x00FF));
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
|
||||
|
||||
// Switch to receive mode
|
||||
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));
|
||||
|
||||
// Read all bytes and disable ACK on last byte
|
||||
for(cur_pos = 0; cur_pos < length; cur_pos++) {
|
||||
if(cur_pos == length - 1) {
|
||||
I2C_AcknowledgeConfig(I2C1, DISABLE);
|
||||
|
@ -40,6 +45,7 @@ void eeprom_read(uint16_t address, uint8_t *data, uint16_t length)
|
|||
data[cur_pos] = I2C_ReceiveData(I2C1);
|
||||
}
|
||||
|
||||
// Send stop condition
|
||||
I2C_GenerateSTOP(I2C1, ENABLE);
|
||||
}
|
||||
|
||||
|
@ -49,9 +55,13 @@ void eeprom_write(uint16_t address, uint8_t *data, uint16_t length)
|
|||
uint16_t cur_pos = 0;
|
||||
address = address & 0xFFA0;
|
||||
|
||||
// If more than one page is needed, cycle over the pages
|
||||
for(cur_page = 0; cur_page <= ((length-1)/64); cur_page++) {
|
||||
// Wait 5 ms for the write cycle (see datasheet)
|
||||
while((SysTickCnt - last_write_tick) <= 5);
|
||||
// Send start condition
|
||||
I2C_GenerateSTART(I2C1, ENABLE);
|
||||
// Send EEPROM address and start address of data to send
|
||||
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));
|
||||
|
@ -60,11 +70,13 @@ void eeprom_write(uint16_t address, uint8_t *data, uint16_t length)
|
|||
I2C_SendData(I2C1, (address & 0x00FF));
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
|
||||
|
||||
// Send max 64 bytes (1 page) of data
|
||||
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));
|
||||
}
|
||||
|
||||
// Generate stop condition and calculate address of next page (if needed)
|
||||
I2C_GenerateSTOP(I2C1, ENABLE);
|
||||
address += 0x0040;
|
||||
last_write_tick = SysTickCnt;
|
||||
|
|
|
@ -6,104 +6,125 @@ uint8_t usart3_inited = 0;
|
|||
|
||||
void i2c1_init(void)
|
||||
{
|
||||
// If I2C1 is already inited, do nothing
|
||||
if (i2c1_inited == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable GPIOB and I2C1 clocks
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
|
||||
|
||||
// Create gpio struct and fill default values
|
||||
GPIO_InitTypeDef gpio;
|
||||
GPIO_StructInit(&gpio);
|
||||
|
||||
// SCL
|
||||
// Set PB6 to alternate function push pull (SCL)
|
||||
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
gpio.GPIO_Pin = GPIO_Pin_6;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
||||
// SDA
|
||||
// Set PB7 to alternate function open drain (SDA)
|
||||
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
|
||||
gpio.GPIO_Pin = GPIO_Pin_7;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
||||
// Set I2C1 clock to 400 kHz
|
||||
I2C_InitTypeDef i2c;
|
||||
I2C_StructInit(&i2c);
|
||||
i2c.I2C_ClockSpeed = 400000;
|
||||
I2C_Init(I2C1, &i2c);
|
||||
|
||||
// Enable I2C1
|
||||
I2C_Cmd(I2C1, ENABLE);
|
||||
i2c1_inited = 1;
|
||||
}
|
||||
|
||||
void usart1_init(void)
|
||||
{
|
||||
// If USART1 is inited, do nothing
|
||||
if (usart1_inited == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable GPIOA and USART1 clocks
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||
|
||||
// Create gpio struct and fill default values
|
||||
GPIO_InitTypeDef gpio;
|
||||
GPIO_StructInit(&gpio);
|
||||
|
||||
// TxD
|
||||
// Set PA9 to alternate function push pull (TxD)
|
||||
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
gpio.GPIO_Pin = GPIO_Pin_9;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
// RxD
|
||||
// Set PA10 to input floating (RxD)
|
||||
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
gpio.GPIO_Pin = GPIO_Pin_10;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
// Set USART1 clock to 115 200 baud
|
||||
USART_InitTypeDef usart;
|
||||
USART_StructInit(&usart);
|
||||
usart.USART_BaudRate = 115200;
|
||||
USART_Init(USART1, &usart);
|
||||
|
||||
// Init USART1 clocks
|
||||
USART_ClockInitTypeDef usartclock;
|
||||
USART_ClockStructInit(&usartclock);
|
||||
USART_ClockInit(USART1, &usartclock);
|
||||
|
||||
// Enable USART1
|
||||
USART_Cmd(USART1, ENABLE);
|
||||
usart1_inited = 1;
|
||||
}
|
||||
|
||||
void usart3_init(void)
|
||||
{
|
||||
// If USART3 is inited, do nothing
|
||||
if (usart3_inited == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable GPIOB and USART3 clocks
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||||
|
||||
// Create gpio struct and fill default values
|
||||
GPIO_InitTypeDef gpio;
|
||||
GPIO_StructInit(&gpio);
|
||||
|
||||
// TxD
|
||||
// Set PB10 to alternate function push pull (TxD)
|
||||
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
gpio.GPIO_Pin = GPIO_Pin_10;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
||||
// RxD
|
||||
// Set PB11 to input floating (RxD)
|
||||
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
gpio.GPIO_Pin = GPIO_Pin_11;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
||||
// Set USART3 clock to 115 200 baud
|
||||
USART_InitTypeDef usart;
|
||||
USART_StructInit(&usart);
|
||||
usart.USART_BaudRate = 115200;
|
||||
USART_Init(USART3, &usart);
|
||||
|
||||
// Init USART3 clocks
|
||||
USART_ClockInitTypeDef usartclock;
|
||||
USART_ClockStructInit(&usartclock);
|
||||
USART_ClockInit(USART3, &usartclock);
|
||||
|
||||
// Enable USART3
|
||||
USART_Cmd(USART3, ENABLE);
|
||||
usart3_inited = 1;
|
||||
}
|
||||
|
||||
void USART_SendString(USART_TypeDef *USARTx, char *str)
|
||||
{
|
||||
// Send a string, byte by byte over the specified USART
|
||||
while (*str) {
|
||||
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
|
||||
USART_SendData(USARTx, *str++);
|
||||
|
|
|
@ -7,46 +7,63 @@
|
|||
|
||||
int main()
|
||||
{
|
||||
// Variables needed
|
||||
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};
|
||||
uint8_t bX[BUFFER_SIZE] = {128}, bY[BUFFER_SIZE] = {128}, bZ[BUFFER_SIZE] = {128}; // 128 is the 'zero' line in the display, so the array is initzialized to 128
|
||||
uint16_t buffer_pos = 0;
|
||||
|
||||
// Init everything we need
|
||||
disp_init();
|
||||
systick_init();
|
||||
bma_init();
|
||||
eeprom_init();
|
||||
bluetooth_init();
|
||||
|
||||
// Enable display
|
||||
disp_enable();
|
||||
|
||||
// Main loop
|
||||
for (;;) {
|
||||
// Check if button is pressed
|
||||
current_state = disp_get_last_state();
|
||||
if(current_state == DISP_STATE_START) {
|
||||
// If start button set running to true
|
||||
running = 1;
|
||||
} else if(current_state == DISP_STATE_PAUSE) {
|
||||
// On pause set running to false
|
||||
running = 0;
|
||||
}
|
||||
// Only read and send data if display is actually running
|
||||
if(running == 1) {
|
||||
// Get accelerations
|
||||
bma_get_acc(&X, &Y, &Z);
|
||||
// Put them into the buffer (for save/recall)
|
||||
bX[buffer_pos] = X;
|
||||
bY[buffer_pos] = Y;
|
||||
bZ[buffer_pos] = Z;
|
||||
// Send data to display and bluetooth
|
||||
disp_send_gyro_data(X, Y, Z);
|
||||
bluetooth_send_gyro_data(X, Y, Z);
|
||||
// Increment buffer position
|
||||
buffer_pos++;
|
||||
if(buffer_pos == BUFFER_SIZE) {
|
||||
// If buffer size is reached, return to 0 (ringbuffer)
|
||||
buffer_pos = 0;
|
||||
}
|
||||
}
|
||||
if(current_state == DISP_STATE_SAVE) {
|
||||
// On save, send the three arrays to the EEPROM
|
||||
eeprom_write(0x0000, bX, BUFFER_SIZE);
|
||||
eeprom_write(0x0400, bY, BUFFER_SIZE);
|
||||
eeprom_write(0x0800, bZ, BUFFER_SIZE);
|
||||
}
|
||||
if(current_state == DISP_STATE_RECALL) {
|
||||
// On recall read the three arrays from EEPROM
|
||||
eeprom_read(0x0000, bX, BUFFER_SIZE);
|
||||
eeprom_read(0x0400, bY, BUFFER_SIZE);
|
||||
eeprom_read(0x0800, bZ, BUFFER_SIZE);
|
||||
// Also update display and bluetooth completely with the new data in the buffer
|
||||
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]);
|
||||
|
|
|
@ -4,20 +4,24 @@ volatile uint32_t SysTickCnt;
|
|||
|
||||
void SysTick_Handler()
|
||||
{
|
||||
// SysTick_Handler increments SysTickCnt
|
||||
SysTickCnt++;
|
||||
}
|
||||
|
||||
void systick_init(void)
|
||||
{
|
||||
// Init the systick clocks to a T = 1 ms
|
||||
RCC_ClocksTypeDef clocks;
|
||||
RCC_GetClocksFreq(&clocks);
|
||||
SysTick_Config(clocks.HCLK_Frequency/1000 - 1);
|
||||
|
||||
// Set count to 0
|
||||
SysTickCnt = 0;
|
||||
}
|
||||
|
||||
void Wait(uint32_t ms)
|
||||
{
|
||||
// Wait specified time in milliseconds
|
||||
uint32_t SysTickCntHold = SysTickCnt;
|
||||
while((SysTickCnt - SysTickCntHold) <= ms);
|
||||
while((SysTickCnt - SysTickCntHold) <= ms);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue