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,34 +2,38 @@
|
|||
|
||||
void init_bma(void)
|
||||
{
|
||||
// Init GPIOB and I2C1 clocks
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
|
||||
|
||||
// Create gpio struct and fill it with default values
|
||||
GPIO_InitTypeDef gpio;
|
||||
GPIO_StructInit(&gpio);
|
||||
|
||||
// SCL
|
||||
// Change default values for SCL port, init port
|
||||
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
gpio.GPIO_Pin = GPIO_Pin_6;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
||||
// SDA
|
||||
// Change default values for SDA port, init port
|
||||
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
|
||||
gpio.GPIO_Pin = GPIO_Pin_7;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
||||
// Create i2c struct, fill it with default values, change clock to 400 kHz and init I2C
|
||||
I2C_InitTypeDef i2c;
|
||||
I2C_StructInit(&i2c);
|
||||
i2c.I2C_ClockSpeed = 400000;
|
||||
I2C_Init(I2C1, &i2c);
|
||||
|
||||
// Enable I2C1 interface
|
||||
I2C_Cmd(I2C1, ENABLE);
|
||||
}
|
||||
|
||||
void run_bma(float acc_f[3])
|
||||
{
|
||||
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);
|
||||
|
@ -38,39 +42,42 @@ void run_bma(float acc_f[3])
|
|||
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 float values, with a maximum amplitude of 2.0g, as described in the datasheet
|
||||
acc_f[0] = 2.0f * ((float)acc[0]/512);
|
||||
acc_f[1] = 2.0f * ((float)acc[1]/512);
|
||||
acc_f[2] = 2.0f * ((float)acc[2]/512);
|
||||
|
@ -78,6 +85,7 @@ void run_bma(float acc_f[3])
|
|||
|
||||
void deinit_bma(void)
|
||||
{
|
||||
// Disable I2C1 and de-init it
|
||||
I2C_Cmd(I2C1, DISABLE);
|
||||
I2C_DeInit(I2C1);
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
#include "stm32f10x_i2c.h" // Keil::Device:StdPeriph Drivers:I2C
|
||||
|
||||
#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 init_bma(void);
|
||||
void run_bma(float acc_f[3]);
|
||||
|
|
|
@ -16,38 +16,49 @@ char colors[COLORS][7] = {
|
|||
|
||||
void init_display(void)
|
||||
{
|
||||
// Init GPIOB and USART3 clocks
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||||
|
||||
// Create gpio struct and fill it with default values
|
||||
GPIO_InitTypeDef gpio;
|
||||
GPIO_StructInit(&gpio);
|
||||
|
||||
// Set PB10 to alternate function push pull
|
||||
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
gpio.GPIO_Pin = GPIO_Pin_10;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
||||
// Set PB11 to input floating
|
||||
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
gpio.GPIO_Pin = GPIO_Pin_11;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
||||
// Create usart struct and set USART3 to 9600 baud
|
||||
USART_InitTypeDef usart;
|
||||
USART_StructInit(&usart);
|
||||
usart.USART_BaudRate = 9600;
|
||||
USART_Init(USART3, &usart);
|
||||
|
||||
// Init USART clock
|
||||
USART_ClockInitTypeDef usartclock;
|
||||
USART_ClockStructInit(&usartclock);
|
||||
USART_ClockInit(USART3, &usartclock);
|
||||
|
||||
// Enable USART3
|
||||
USART_Cmd(USART3, ENABLE);
|
||||
}
|
||||
|
||||
void run_display(void)
|
||||
{
|
||||
// String to store command
|
||||
char cmd[16], *cptr;
|
||||
cptr = cmd;
|
||||
// Fill string with every color from colors[]
|
||||
sprintf(cmd, "cls %s\xFF\xFF\xFF", colors[i++]);
|
||||
// If the last color is reached, begin again
|
||||
if (i == COLORS) i = 0;
|
||||
// Send character for character to USART3 (the display)
|
||||
while(*cptr) {
|
||||
while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
|
||||
USART_SendData(USART3, *cptr++);
|
||||
|
@ -56,12 +67,16 @@ void run_display(void)
|
|||
|
||||
void deinit_display(void)
|
||||
{
|
||||
// Reset command
|
||||
char *cmd = "rest\xFF\xFF\xFF";
|
||||
// Reset the display after the test finishes
|
||||
while(*cmd) {
|
||||
while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
|
||||
USART_SendData(USART3, *cmd++);
|
||||
}
|
||||
// Wait till the last character is sent
|
||||
while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
|
||||
// Then disable USART3 again
|
||||
USART_Cmd(USART3, DISABLE);
|
||||
USART_DeInit(USART3);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ volatile uint32_t *EEPROMSTick, EEPROMSTickCur;
|
|||
uint8_t load_byte(uint16_t eeprom_addr)
|
||||
{
|
||||
uint8_t data;
|
||||
// Send address to read from
|
||||
I2C_GenerateSTART(I2C1, ENABLE);
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
|
||||
I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
|
||||
|
@ -14,20 +15,24 @@ uint8_t load_byte(uint16_t eeprom_addr)
|
|||
I2C_SendData(I2C1, (eeprom_addr & 0x00FF));
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
|
||||
|
||||
// Switch to Rx mode
|
||||
I2C_GenerateSTART(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));
|
||||
|
||||
// Load byte
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
|
||||
data = I2C_ReceiveData(I2C1);
|
||||
I2C_GenerateSTOP(I2C1, ENABLE);
|
||||
|
||||
// Return data byte
|
||||
return data;
|
||||
}
|
||||
|
||||
void write_byte(uint16_t eeprom_addr, uint8_t data)
|
||||
{
|
||||
// Send address to write to
|
||||
I2C_GenerateSTART(I2C1, ENABLE);
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
|
||||
I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
|
||||
|
@ -37,11 +42,12 @@ void write_byte(uint16_t eeprom_addr, uint8_t data)
|
|||
I2C_SendData(I2C1, (eeprom_addr & 0x00FF));
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
|
||||
|
||||
// Send data byte
|
||||
I2C_SendData(I2C1, data);
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
|
||||
|
||||
I2C_GenerateSTOP(I2C1, ENABLE);
|
||||
|
||||
// Wait 5 ms to satisfy the write cycle time of the EEPROM
|
||||
EEPROMSTickCur = *EEPROMSTick;
|
||||
while((*EEPROMSTick - EEPROMSTickCur) <= 50); // 5ms write cycle, see datasheet param 17
|
||||
return;
|
||||
|
@ -49,27 +55,31 @@ void write_byte(uint16_t eeprom_addr, uint8_t data)
|
|||
|
||||
void init_eeprom(volatile uint32_t *SysTickCnt)
|
||||
{
|
||||
// Enable GPIOB and I2C1 cloc
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
|
||||
|
||||
// Create gpio struct and fill it with 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 I2C clock to 400 kHz
|
||||
I2C_InitTypeDef i2c;
|
||||
I2C_StructInit(&i2c);
|
||||
i2c.I2C_ClockSpeed = 400000;
|
||||
I2C_Init(I2C1, &i2c);
|
||||
|
||||
// Enable I2C1 and save SysTick pointer
|
||||
I2C_Cmd(I2C1, ENABLE);
|
||||
EEPROMSTick = SysTickCnt;
|
||||
return;
|
||||
|
@ -77,6 +87,7 @@ void init_eeprom(volatile uint32_t *SysTickCnt)
|
|||
|
||||
void run_eeprom(uint8_t *success)
|
||||
{
|
||||
// Write some data to some addresses and check if the date matches after a read, if not, return
|
||||
uint8_t set, read;
|
||||
*success = 0;
|
||||
set = 0xAA;
|
||||
|
@ -111,12 +122,14 @@ void run_eeprom(uint8_t *success)
|
|||
write_byte(0x0005, set);
|
||||
read = load_byte(0x0005);
|
||||
if (set != read) return;
|
||||
// If everything matches, set success to true and then return
|
||||
*success = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
void deinit_eeprom(void)
|
||||
{
|
||||
// Disable I2C1
|
||||
I2C_Cmd(I2C1, DISABLE);
|
||||
I2C_DeInit(I2C1);
|
||||
return;
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
#include "stm32f10x_i2c.h" // Keil::Device:StdPeriph Drivers:I2C
|
||||
|
||||
#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())
|
||||
|
||||
void init_eeprom(volatile uint32_t *SysTickCnt);
|
||||
void run_eeprom(uint8_t *success);
|
||||
|
|
|
@ -2,29 +2,36 @@
|
|||
|
||||
void init_esp(void)
|
||||
{
|
||||
// Enable GPIOa and USART2 clocks
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
|
||||
// Create gpio struct and fill it with default values
|
||||
GPIO_InitTypeDef gpio;
|
||||
GPIO_StructInit(&gpio);
|
||||
|
||||
// Set PB2 to alternate function push pull (Tx)
|
||||
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
gpio.GPIO_Pin = GPIO_Pin_2;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
// Set PB3 to input floating (Rx)
|
||||
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
gpio.GPIO_Pin = GPIO_Pin_3;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
// Create usart struct and init USART2 to 115 200 baud
|
||||
USART_InitTypeDef usart;
|
||||
USART_StructInit(&usart);
|
||||
usart.USART_BaudRate = 115200;
|
||||
USART_Init(USART2, &usart);
|
||||
|
||||
// Init USART2 clock
|
||||
USART_ClockInitTypeDef usartclock;
|
||||
USART_ClockStructInit(&usartclock);
|
||||
USART_ClockInit(USART2, &usartclock);
|
||||
|
||||
// Init NVIC for USART2 RXNE to see stuff sent to the TCP server. The ISR is in main.c
|
||||
NVIC_InitTypeDef nvic;
|
||||
nvic.NVIC_IRQChannel = USART2_IRQn;
|
||||
nvic.NVIC_IRQChannelCmd = ENABLE;
|
||||
|
@ -33,11 +40,13 @@ void init_esp(void)
|
|||
NVIC_Init(&nvic);
|
||||
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
|
||||
|
||||
// Enable USART2
|
||||
USART_Cmd(USART2, ENABLE);
|
||||
}
|
||||
|
||||
void esp_wait()
|
||||
{
|
||||
// Wait some time so the ESP can execute the commands sent
|
||||
int i, j;
|
||||
for(j=0;j<500;j++) {
|
||||
for(i=0;i<65536;i++);
|
||||
|
@ -45,6 +54,7 @@ void esp_wait()
|
|||
}
|
||||
|
||||
void send_str(char *str) {
|
||||
// Sends a string over UART
|
||||
while(*str) {
|
||||
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
|
||||
USART_SendData(USART2, *str++);
|
||||
|
@ -53,23 +63,31 @@ void send_str(char *str) {
|
|||
|
||||
void run_esp(void)
|
||||
{
|
||||
// Restore the ESP to defaults, then wait
|
||||
send_str("AT+RESTORE\r\n");
|
||||
esp_wait();
|
||||
// Print out the current mode
|
||||
send_str("AT+CWMODE?\r\n");
|
||||
esp_wait();
|
||||
// Set mode to access point
|
||||
send_str("AT+CWMODE=2\r\n");
|
||||
esp_wait();
|
||||
// Reset
|
||||
send_str("AT+RST\r\n");
|
||||
esp_wait();
|
||||
// Enable access point
|
||||
send_str("AT+CIPMUX=1\r\n");
|
||||
esp_wait();
|
||||
// Start TCP server on port 2526
|
||||
send_str("AT+CIPSERVER=1,2526\r\n");
|
||||
esp_wait();
|
||||
// Print out the current IP address
|
||||
send_str("AT+CIPAP_CUR?\r\n");
|
||||
}
|
||||
|
||||
void deinit_esp(void)
|
||||
{
|
||||
// Disable the interrupt, then disable USART2
|
||||
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
|
||||
USART_Cmd(USART2, DISABLE);
|
||||
USART_DeInit(USART2);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
void USART_SendString(USART_TypeDef *USARTx, char *str)
|
||||
{
|
||||
// Sends a string, character for character, over the specified UART
|
||||
while (*str) {
|
||||
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
|
||||
USART_SendData(USARTx, *str++);
|
||||
|
@ -10,35 +11,44 @@ void USART_SendString(USART_TypeDef *USARTx, char *str)
|
|||
|
||||
void init_all(void)
|
||||
{
|
||||
// Enable all GPIO and USART clocks needed for USART1, 2 and 3
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||||
|
||||
// Create gpio struct and fill it with defaults
|
||||
GPIO_InitTypeDef gpio;
|
||||
GPIO_StructInit(&gpio);
|
||||
|
||||
// Set PA9 to alternate function push pull (Tx)
|
||||
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
gpio.GPIO_Pin = GPIO_Pin_9;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
// Same for PA2
|
||||
gpio.GPIO_Pin = GPIO_Pin_2;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
// Same for PB10
|
||||
gpio.GPIO_Pin = GPIO_Pin_10;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
||||
// Set PA10 to input floating (Rx)
|
||||
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
gpio.GPIO_Pin = GPIO_Pin_10;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
// Same for PA3
|
||||
gpio.GPIO_Pin = GPIO_Pin_3;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
// Same for PB11
|
||||
gpio.GPIO_Pin = GPIO_Pin_11;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
||||
// Create usart struct and set baud rate to 115 200, init all three USARTs with this baud rate
|
||||
USART_InitTypeDef usart;
|
||||
USART_StructInit(&usart);
|
||||
usart.USART_BaudRate = 115200;
|
||||
|
@ -46,16 +56,19 @@ void init_all(void)
|
|||
USART_Init(USART2, &usart);
|
||||
USART_Init(USART3, &usart);
|
||||
|
||||
// Enable USART clocks
|
||||
USART_ClockInitTypeDef usartclock;
|
||||
USART_ClockStructInit(&usartclock);
|
||||
USART_ClockInit(USART1, &usartclock);
|
||||
USART_ClockInit(USART2, &usartclock);
|
||||
USART_ClockInit(USART3, &usartclock);
|
||||
|
||||
// Enable the USARTs
|
||||
USART_Cmd(USART1, ENABLE);
|
||||
USART_Cmd(USART2, ENABLE);
|
||||
USART_Cmd(USART3, ENABLE);
|
||||
|
||||
// Enable the SysTick with T = 1 ms
|
||||
RCC_ClocksTypeDef clocks;
|
||||
RCC_GetClocksFreq(&clocks);
|
||||
SysTick_Config(clocks.HCLK_Frequency/1000 - 1); // SysTick T=1ms
|
||||
|
@ -63,6 +76,7 @@ void init_all(void)
|
|||
|
||||
void send_welcome(void)
|
||||
{
|
||||
// Send a welcome message to all three USARTs
|
||||
USART_SendString(USART1, "\x1B[2J\x1B[0;0HManufacturing test software, press space...\r\n");
|
||||
USART_SendString(USART2, "\x1B[2J\x1B[0;0HManufacturing test software, press space...\r\n");
|
||||
USART_SendString(USART3, "\x1B[2J\x1B[0;0HManufacturing test software, press space...\r\n");
|
||||
|
@ -71,10 +85,14 @@ void send_welcome(void)
|
|||
unsigned int wait_for_start(void)
|
||||
{
|
||||
uint8_t data;
|
||||
// Runs until space has been pressed on one UART
|
||||
for(;;) {
|
||||
// Checks if USART1 receive register is not empty
|
||||
if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET) {
|
||||
data = USART_ReceiveData(USART1);
|
||||
// Checks if space has been pressed
|
||||
if (data == ' ') {
|
||||
// Disable the other UARTs and return 1 as this is the used UART
|
||||
USART_Cmd(USART2, DISABLE);
|
||||
USART_Cmd(USART3, DISABLE);
|
||||
USART_DeInit(USART2);
|
||||
|
@ -85,9 +103,12 @@ unsigned int wait_for_start(void)
|
|||
USART_DeInit(USART1);
|
||||
}
|
||||
}
|
||||
// Checks if USART2 receive register is not empty
|
||||
if (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == SET) {
|
||||
data = USART_ReceiveData(USART2);
|
||||
// Checks if space has been pressed
|
||||
if (data == ' ') {
|
||||
// Disable the other UARTs and return 2 as this is the used UART
|
||||
USART_Cmd(USART1, DISABLE);
|
||||
USART_Cmd(USART3, DISABLE);
|
||||
USART_DeInit(USART1);
|
||||
|
@ -98,9 +119,12 @@ unsigned int wait_for_start(void)
|
|||
USART_DeInit(USART2);
|
||||
}
|
||||
}
|
||||
// Checks if USART3 receive register is not empty
|
||||
if (USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == SET) {
|
||||
data = USART_ReceiveData(USART3);
|
||||
// Checks if space has been pressed
|
||||
if (data == ' ') {
|
||||
// Disable the other UARTs and return 3 as this is the used UART
|
||||
USART_Cmd(USART1, DISABLE);
|
||||
USART_Cmd(USART2, DISABLE);
|
||||
USART_DeInit(USART1);
|
||||
|
@ -117,11 +141,15 @@ unsigned int wait_for_start(void)
|
|||
unsigned int wait_for_test(USART_TypeDef *USARTx)
|
||||
{
|
||||
int data;
|
||||
// Blocks until something is pressed
|
||||
for(;;)
|
||||
{
|
||||
// Checks if receive register is not empty
|
||||
if (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == SET) {
|
||||
data = (int)USART_ReceiveData(USARTx);
|
||||
if ((data > 0x09 && data <= 0x30) || data > 0x39) return 1;
|
||||
// If data is out of range return 1 (no test)
|
||||
if ((data > 0x09 && data <= 0x30) || data > 0x39) return 1;
|
||||
// Else return the correct test id
|
||||
return (data >= 0x30) ? data - 0x30 : data;
|
||||
}
|
||||
}
|
||||
|
@ -130,10 +158,14 @@ unsigned int wait_for_test(USART_TypeDef *USARTx)
|
|||
unsigned int get_test(USART_TypeDef *USARTx)
|
||||
{
|
||||
int data;
|
||||
// Checks if receive register is not empty
|
||||
if (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == SET) {
|
||||
data = (int)USART_ReceiveData(USARTx);
|
||||
if ((data > 0x09 && data <= 0x30) || data > 0x39) return 1;
|
||||
// If data is out of range return 1 (no test)
|
||||
if ((data > 0x09 && data <= 0x30) || data > 0x39) return 1;
|
||||
// Else return the correct test id
|
||||
return (data >= 0x30) ? data - 0x30 : data;
|
||||
}
|
||||
// If nothing has been sent to the UART, return 0 (test not changed)
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2,16 +2,20 @@
|
|||
|
||||
void init_ledswitch(void)
|
||||
{
|
||||
// Init GPIOA and GPIOC clocks
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
|
||||
|
||||
// Create gpio struct and fill it with defaults
|
||||
GPIO_InitTypeDef gpio;
|
||||
GPIO_StructInit(&gpio);
|
||||
|
||||
// Set the LED ports to push pull
|
||||
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
gpio.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
|
||||
GPIO_Init(GPIOC, &gpio);
|
||||
|
||||
// Set the switch ports to input pull up
|
||||
gpio.GPIO_Mode = GPIO_Mode_IPU;
|
||||
gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
@ -20,7 +24,9 @@ void init_ledswitch(void)
|
|||
|
||||
void run_ledswitch(uint8_t *switches)
|
||||
{
|
||||
// Read switches and shift it to represent a 8 bit number
|
||||
*switches = (GPIO_ReadInputData(GPIOA) & 0x000F) | ((GPIO_ReadInputData(GPIOA) & 0x01E0) >> 1);
|
||||
// Write that 8 bit number correctly shifted again to the LEDs
|
||||
GPIO_Write(GPIOC, ((*switches & 0xE0) << 2) | ((*switches & 0x1F) << 1));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -17,33 +17,43 @@ USART_TypeDef *used_usart;
|
|||
|
||||
void SysTick_Handler()
|
||||
{
|
||||
// Increment SysTickCnt
|
||||
SysTickCnt++;
|
||||
}
|
||||
|
||||
void USART2_IRQHandler()
|
||||
{
|
||||
// Print received data to the used UART
|
||||
USART_SendData(used_usart, USART_ReceiveData(USART2));
|
||||
}
|
||||
|
||||
void wait(uint32_t ms)
|
||||
{
|
||||
uint32_t SysTickCntHold = SysTickCnt;
|
||||
while((SysTickCnt - SysTickCntHold) <= ms);
|
||||
// Wait the specified time in milliseconds
|
||||
uint32_t SysTickCntHold = SysTickCnt;
|
||||
while((SysTickCnt - SysTickCntHold) <= ms);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
char buffer[1024];
|
||||
// Create test and next test enum, set both to not init
|
||||
enum test_t current_test = test_not_init, next_test = test_not_init;
|
||||
// Create interface enum, set it to none
|
||||
enum iface_t control_interface = interface_none;
|
||||
|
||||
// Endless main loop
|
||||
for (;;) {
|
||||
// Switch the interface
|
||||
switch (control_interface) {
|
||||
// If no interface has been specified, init everything, print welcome and wait for specification
|
||||
case interface_none:
|
||||
init_all();
|
||||
send_welcome();
|
||||
control_interface = (enum iface_t)wait_for_start();
|
||||
// Switch thru the return value
|
||||
switch (control_interface) {
|
||||
// Set used_usart to the right one, depeinding on the selected interface
|
||||
case interface_usart1:
|
||||
used_usart = USART1;
|
||||
break;
|
||||
|
@ -53,45 +63,61 @@ int main()
|
|||
case interface_usart3:
|
||||
used_usart = USART3;
|
||||
break;
|
||||
default:
|
||||
// If there is no one, set it back to none and do everything again
|
||||
default:
|
||||
control_interface = interface_none;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// If a interface is specified look up the test to du
|
||||
case interface_usart1:
|
||||
case interface_usart2:
|
||||
case interface_usart3:
|
||||
// Switch thru the tests
|
||||
switch(current_test) {
|
||||
// If not inited, set the test to none
|
||||
case test_not_init:
|
||||
current_test = test_none;
|
||||
break;
|
||||
// If none, print main menu and wait for a test to be selected
|
||||
case test_none:
|
||||
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HManufacturing test software, Version " VERSION "\r\n\r\n\
|
||||
\tTo run tests, enter one of the following numbers:\r\n\t\t[2]\tBMA\r\n\t\t[3]\tNE555/LFU/IR\r\n\
|
||||
\t\t[4]\tLEDs and Switches\r\n\t\t[5]\tESP\r\n\t\t[6]\tEEPROM\r\n\t\t[7]\tRGB LED\r\n\t\t[8]\tPiezo\r\n\t\t[9]\tDisplay\r\n\r\nWaiting for your selection... ");
|
||||
current_test = (enum test_t)wait_for_test(used_usart);
|
||||
break;
|
||||
// Else print the page for the selected test and then run it
|
||||
case test_bma:
|
||||
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HBMA Test\r\n\r\nThis tests the correct function\
|
||||
of the used BMA gyroscope as well as I2C port 1. Below you should see the current acceleration values printed\
|
||||
for the X, Y and Z axis. Where the Z axis should show something around 1g, as this is the gravitational\
|
||||
acceleration on the Earth, of course this value is lower if you run this program on the moon!\r\n\r\n\
|
||||
To return to the main menu press a button.\r\n\r\n\r\n");
|
||||
// Init the test and create variables if needed
|
||||
init_bma();
|
||||
float accs[3];
|
||||
// Test loop
|
||||
for(;;) {
|
||||
// Run the test (here: get the acceleration avlues)
|
||||
run_bma(accs);
|
||||
// Print the values to the interface
|
||||
sprintf(buffer, "\x1B[K\rX: % 02.5f, Y: % 02.5f, Z: % 02.5f", accs[0], accs[1], accs[2]);
|
||||
USART_SendString(used_usart, buffer);
|
||||
// Check if there is a new test (or main menu) selected
|
||||
next_test = (enum test_t)get_test(used_usart);
|
||||
if (next_test != test_not_init) {
|
||||
// If the new test differs from the current one, change the current one so that in the next run of the main loop the right test gets executed
|
||||
current_test = next_test;
|
||||
// DeInit the peripherals used for the test
|
||||
deinit_bma();
|
||||
// Leave the test loop, let the main mloop continue to run
|
||||
break;
|
||||
}
|
||||
// Wait some time to be able to read the returned values
|
||||
wait(50);
|
||||
}
|
||||
break;
|
||||
// Run NE555/LFU/IR test, for more information about the executed commands see BMA test (above)
|
||||
case test_ne555:
|
||||
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HNE555/LFU/IR Test\r\n\r\nThis tests the correct function\
|
||||
of the NE555/LFU/IR on the board. The currently selected frequency should be printed below!\r\n\r\n\
|
||||
|
@ -111,6 +137,7 @@ To return to the main menu press a button.\r\n\r\n\r\n");
|
|||
wait(50);
|
||||
}
|
||||
break;
|
||||
// Run LED/Switch test, for more information about the executed commands see BMA test (above)
|
||||
case test_led:
|
||||
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HLED/Switch Test\r\n\r\nThis tests the correct function\
|
||||
of the switches and the leds on the board. The currently selected leds are shown hexadecimal below!\r\n\r\n\
|
||||
|
@ -130,6 +157,7 @@ To return to the main menu press a button.\r\n\r\n\r\n");
|
|||
wait(50);
|
||||
}
|
||||
break;
|
||||
// Run ESP test, for more information about the executed commands see BMA test (above)
|
||||
case test_esp:
|
||||
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HESP Test\r\n\r\nThis tests the correct function\
|
||||
of the ESP module on the board. The ESP should open a WLAN AP!\r\n\r\n\
|
||||
|
@ -148,6 +176,7 @@ To return to the main menu press a button.\r\n\r\n\r\n");
|
|||
wait(50);
|
||||
}
|
||||
break;
|
||||
// Run EEPROM test, for more information about the executed commands see BMA test (above)
|
||||
case test_eeprom:
|
||||
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HEEPROM Test\r\n\r\nThis tests the correct function\
|
||||
of the EEPROM on the board. The test will run and show an OK or NOK below!\r\n\r\n\
|
||||
|
@ -170,6 +199,7 @@ To return to the main menu press a button.\r\n\r\n\r\n");
|
|||
wait(50);
|
||||
}
|
||||
break;
|
||||
// Run RGB LED test, for more information about the executed commands see BMA test (above)
|
||||
case test_rgb:
|
||||
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HRGB LED Test\r\n\r\nThis tests the correct function\
|
||||
of the RGB LED and it's I2C driver on the board!\r\n\r\n\
|
||||
|
@ -186,6 +216,7 @@ To return to the main menu press a button.\r\n\r\n\r\n");
|
|||
wait(50);
|
||||
}
|
||||
break;
|
||||
// Run Piezo test, for more information about the executed commands see BMA test (above)
|
||||
case test_piezo:
|
||||
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HPiezo Test\r\n\r\nThis tests the correct function\
|
||||
of the Piezo on the board. You should hear the frequency printed below!\r\n\r\n\
|
||||
|
@ -204,6 +235,7 @@ To return to the main menu press a button.\r\n\r\n\r\n");
|
|||
wait(50);
|
||||
}
|
||||
break;
|
||||
// Run display test, for more information about the executed commands see BMA test (above)
|
||||
case test_display:
|
||||
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HDisplay Test\r\n\r\nThis tests the correct function\
|
||||
of the Display on the board. You should see text printed on the display!\r\n\r\n\
|
||||
|
@ -222,6 +254,7 @@ To return to the main menu press a button.\r\n\r\n\r\n");
|
|||
wait(50);
|
||||
}
|
||||
break;
|
||||
// If test does not exist, go to main menu
|
||||
default:
|
||||
current_test = test_none;
|
||||
break;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
// Define program version
|
||||
#define VERSION "0.1.0"
|
||||
|
||||
// Define interfaces which can be used
|
||||
enum iface_t {
|
||||
interface_none = 0,
|
||||
interface_usart1,
|
||||
|
@ -10,6 +12,7 @@ enum iface_t {
|
|||
interface_usart3
|
||||
};
|
||||
|
||||
// Define available tests
|
||||
enum test_t {
|
||||
test_not_init = 0,
|
||||
test_none = 1,
|
||||
|
|
|
@ -5,11 +5,14 @@ uint8_t old_state;
|
|||
|
||||
void init_ne555(volatile uint32_t *SysTickCnt)
|
||||
{
|
||||
// Enable GPIOb clock
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
|
||||
// Create gpio struct and fill it with default values
|
||||
GPIO_InitTypeDef gpio;
|
||||
GPIO_StructInit(&gpio);
|
||||
|
||||
// Set PB0 to input floating
|
||||
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
gpio.GPIO_Pin = GPIO_Pin_0;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
@ -23,15 +26,18 @@ void run_ne555(float *freq)
|
|||
uint8_t state;
|
||||
*freq = 0.0f;
|
||||
NE555STickCur = *NE555STick;
|
||||
// Run for one second
|
||||
while((*NE555STick - NE555STickCur) <= 1000)
|
||||
{
|
||||
state = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0);
|
||||
// If the state changes low -> high or high -> low increment freq and save state
|
||||
if (state != old_state)
|
||||
{
|
||||
(*freq)++;
|
||||
old_state = state;
|
||||
}
|
||||
}
|
||||
// Divide freq by two to get the frequency
|
||||
*freq /= 2;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -4,11 +4,14 @@ volatile uint32_t *PiezoSTick, PiezoSTickCur, Freq;
|
|||
|
||||
void init_piezo(volatile uint32_t *SysTickCnt)
|
||||
{
|
||||
// Enable GPIOB clock
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
|
||||
// Create gpio struct and fill it with default values
|
||||
GPIO_InitTypeDef gpio;
|
||||
GPIO_StructInit(&gpio);
|
||||
|
||||
// Set PB0 to output push pull
|
||||
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
gpio.GPIO_Pin = GPIO_Pin_0;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
@ -21,10 +24,13 @@ void run_piezo()
|
|||
{
|
||||
uint8_t pstate = 0x0;
|
||||
PiezoSTickCur = *PiezoSTick;
|
||||
// Run for one second
|
||||
while((*PiezoSTick - PiezoSTickCur) <= 1000)
|
||||
{
|
||||
Freq = *PiezoSTick;
|
||||
// Wait for 1 millisecond
|
||||
while((*PiezoSTick - Freq) <= 1);
|
||||
// Toggle output
|
||||
if (pstate) {
|
||||
pstate = ~pstate;
|
||||
GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "rgb.h"
|
||||
#include "main.h"
|
||||
|
||||
// Define registers of the RGB LED driver
|
||||
typedef enum {
|
||||
RGB_SHUTDOWN = 0x00,
|
||||
RGB_MAXCUR,
|
||||
|
@ -15,14 +16,17 @@ typedef enum {
|
|||
|
||||
void rgb_send_command(uint8_t data)
|
||||
{
|
||||
// Generate start condition and transmit address
|
||||
I2C_GenerateSTART(I2C1, ENABLE);
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
|
||||
I2C_Send7bitAddress(I2C1, RGB_ADDR, I2C_Direction_Transmitter);
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
|
||||
|
||||
// Send data
|
||||
I2C_SendData(I2C1, data);
|
||||
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
|
||||
|
||||
// Generate stop condition
|
||||
I2C_GenerateSTOP(I2C1, ENABLE);
|
||||
|
||||
return;
|
||||
|
@ -30,36 +34,42 @@ void rgb_send_command(uint8_t data)
|
|||
|
||||
void init_rgb(void)
|
||||
{
|
||||
// Enable GPIOB anf I2C1 clocks
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
|
||||
|
||||
// Create gpio struct and fill it with 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);
|
||||
|
||||
// Init I2C1 to 400 kHz
|
||||
I2C_InitTypeDef i2c;
|
||||
I2C_StructInit(&i2c);
|
||||
i2c.I2C_ClockSpeed = 400000;
|
||||
I2C_Init(I2C1, &i2c);
|
||||
|
||||
// Enable I2C1 driver
|
||||
I2C_Cmd(I2C1, ENABLE);
|
||||
|
||||
// LED actually allows 40mA, but driver only hanbdles around 30
|
||||
// Set the max current the driver should allow
|
||||
// LED actually allows 40mA, but driver only handles around 30
|
||||
rgb_send_command(0x3F);
|
||||
return;
|
||||
}
|
||||
|
||||
void run_rgb(void)
|
||||
{
|
||||
// Set random colors for 100 ms each
|
||||
rgb_send_command(0x5F);
|
||||
wait(100);
|
||||
rgb_send_command(0x7F);
|
||||
|
@ -83,6 +93,7 @@ void run_rgb(void)
|
|||
|
||||
void deinit_rgb(void)
|
||||
{
|
||||
// Disable I2C1
|
||||
I2C_Cmd(I2C1, DISABLE);
|
||||
I2C_DeInit(I2C1);
|
||||
return;
|
||||
|
|
|
@ -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