-
-
Save r00li/e3965849ee128e95faec422a16ef6d6b to your computer and use it in GitHub Desktop.
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
#include "stm32f0xx_conf.h" | |
#include "stdlib.h" | |
#define MillisecondsIT 1e3 | |
volatile uint8_t somearray[500]; | |
volatile int somearray_ind = 0; | |
volatile uint8_t token[500]; | |
volatile int token_start = 0; | |
volatile int token_end = 0; | |
volatile uint8_t token_ready = 0; | |
volatile uint32_t milliseconds = 0; | |
// Interrupt handlers | |
void USART2_IRQHandler(void) | |
{ | |
// | |
// BLE Connection handler - data receive | |
// | |
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) | |
{ | |
if (somearray_ind >= 500) | |
{ | |
// buffer full, start overwriting data - this should not happen | |
somearray_ind = 0; | |
} | |
somearray[somearray_ind] = USART_ReceiveData(USART2); | |
if (somearray[somearray_ind] == '\n') | |
{ | |
if (token_start == token_end) | |
{ | |
token_end = somearray_ind; | |
if (token_end - token_start > 1) | |
{ | |
memcpy(token, &somearray[token_start], token_end - token_start); | |
token[token_end - token_start - 1] = '\0'; | |
token_ready = 1; | |
} | |
else | |
{ | |
token[0] = '\0'; | |
} | |
somearray_ind = 0; | |
token_start = token_end = 0; | |
} | |
else | |
{ | |
token_start = somearray_ind; | |
} | |
} | |
else | |
{ | |
somearray_ind++; | |
} | |
} | |
} | |
void SysTick_Handler(void) | |
{ | |
// | |
// Systick handler - used for delay functionality | |
// | |
milliseconds++; | |
} | |
// Initialization and helper functions | |
void DelayMil(uint32_t MilS) | |
{ | |
// | |
// Millisecond delay function | |
// | |
volatile uint32_t MSStart = milliseconds; | |
while((milliseconds - MSStart)<MilS) __asm__ volatile("nop"); | |
} | |
void USART2_init() | |
{ | |
// | |
// Configuration of the connection with the BLE module | |
// | |
GPIO_InitTypeDef GPIO_InitStruct; | |
USART_InitTypeDef USART_InitStruct; | |
NVIC_InitTypeDef NVIC_InitStructure; | |
// Init clocks | |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); | |
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); | |
// Init GPIO | |
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; | |
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; | |
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz; | |
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; | |
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; | |
GPIO_Init(GPIOA, &GPIO_InitStruct); | |
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_1); | |
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1); | |
// Configure USART | |
USART_InitStruct.USART_BaudRate = 115200; | |
USART_InitStruct.USART_WordLength = USART_WordLength_8b; | |
USART_InitStruct.USART_StopBits = USART_StopBits_1; | |
USART_InitStruct.USART_Parity = USART_Parity_No; | |
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; | |
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; | |
USART_Init(USART2, &USART_InitStruct); | |
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // We want RXNE (data received) interrupts | |
// Init NVIC | |
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; | |
NVIC_InitStructure.NVIC_IRQChannelPriority = 1; | |
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; | |
NVIC_Init(&NVIC_InitStructure); | |
USART_Cmd(USART2, ENABLE); | |
} | |
void USART2_send(char* data) | |
{ | |
// | |
// Sends data to BLE module | |
// For now PIO only | |
// | |
int sent; | |
for (sent = 0; sent < strlen(data); sent++) | |
{ | |
while(!USART_GetFlagStatus(USART2, USART_FLAG_TXE)) {} | |
USART_SendData(USART2, data[sent]); | |
} | |
} | |
void initSwitchGPIO() | |
{ | |
// | |
// Initializes GPIO pins for our switch functionality | |
// Our switch is on Pin GPIOB, Pin 0 | |
// | |
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); | |
GPIO_InitTypeDef GPIO_InitStructure; | |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; | |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; | |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; | |
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; | |
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; | |
GPIO_Init(GPIOB, &GPIO_InitStructure); | |
GPIO_ResetBits(GPIOB, GPIO_Pin_0); | |
} | |
void initMiscGPIO() | |
{ | |
// | |
// Initializes helper pins | |
// PA10 - Blue LED, PA6 - BLE_WAKEHW, PA4 - BLE_WAKESW | |
// We could use these pins to control BLE module power consumption. But we are not doing that since power consumption is not an issue here | |
// | |
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); | |
GPIO_InitTypeDef GPIO_InitStructure; | |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_6 | GPIO_Pin_4; | |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; | |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; | |
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; | |
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; | |
GPIO_Init(GPIOA, &GPIO_InitStructure); | |
GPIO_SetBits(GPIOA, GPIO_Pin_6 | GPIO_Pin_4); | |
} | |
// Switch functionality | |
void setBluetoothSettings() | |
{ | |
// | |
// Configure the RN4020 BLE module according to our wishes | |
// | |
USART2_send("SF,2\n"); // Factory reset | |
DelayMil(1000); | |
USART2_send("S-,RSwitch\n"); // Set our custom device name | |
DelayMil(200); | |
USART2_send("SN,RSwitch\n"); // Set our custom device name | |
DelayMil(200); | |
USART2_send("SDN,roli - www.r00li.com\n"); // Set our custom device name | |
DelayMil(200); | |
USART2_send("SDM,Rswitch v1.0\n"); // Set our custom device name | |
DelayMil(200); | |
USART2_send("PZ\n"); // Clear private services | |
DelayMil(200); | |
USART2_send("SS,80000001\n"); // Enable device info service (0x80000000) and custom service (0x00000001) - bitwise OR | |
DelayMil(200); | |
USART2_send("SR,24004000\n"); // Peripheral mode, no direct advertising, auto advertise, iOS mode | |
DelayMil(200); | |
USART2_send("PS,6A74128071D611E5952A0002A5D5C51B\n"); // Set private service UUID to this UUID (Generated using: http://www.itu.int/en/ITU-T/asn1/Pages/UUID/generate_uuid.aspx ) | |
DelayMil(200); | |
USART2_send("PC,9ED90C0071D711E5977A0002A5D5C51B,1A,01\n"); // Set private characteristic with UUID, set it to read/write/notify (1A) and set it to be 1 byte long (01) | |
DelayMil(200); | |
USART2_send("R,1\n"); // Reboot module | |
DelayMil(5000); | |
} | |
void checkBluetoothSettings() | |
{ | |
// | |
// Checks if our BLE module is configured correctly - if not it rewrites our configuration parameters to it | |
// | |
USART2_send("GN\n"); | |
DelayMil(300); | |
if (strstr(token, "RSwitch") == NULL) | |
{ | |
// Bluetooth module not configured. Configure it! | |
setBluetoothSettings(); | |
} | |
} | |
void processToken() | |
{ | |
// | |
// The core of our switch - main switching functionality | |
// | |
if (strstr(somearray, "WV,0018,FF") != NULL) | |
{ | |
// Light on command | |
GPIO_SetBits(GPIOB, GPIO_Pin_0); // GPIO light switch pin | |
GPIO_SetBits(GPIOA, GPIO_Pin_10); // Blue LED pin | |
} | |
else if (strstr(somearray, "WV,0018,00") != NULL) | |
{ | |
// Light off command | |
GPIO_ResetBits(GPIOB, GPIO_Pin_0); // GPIO light switch pin | |
GPIO_ResetBits(GPIOA, GPIO_Pin_10); // Blue LED pin | |
} | |
} | |
int main(void) | |
{ | |
SystemInit(); // Ensure CPU is running at correctly set clock speed | |
SystemCoreClockUpdate(); // Update SystemCoreClock variable to current clock speed | |
SysTick_Config(SystemCoreClock/MillisecondsIT); // Set up a systick interrupt every millisecond | |
initMiscGPIO(); | |
initSwitchGPIO(); | |
USART2_init(); | |
DelayMil(300); | |
checkBluetoothSettings(); | |
//USART2_send("A\n"); | |
while(1) | |
{ | |
if (token_ready) | |
{ | |
processToken(); | |
token_ready = 0; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment