Skip to content

Instantly share code, notes, and snippets.

@r00li

r00li/main.c Secret

Last active November 19, 2018 21:25
Show Gist options
  • Save r00li/e3965849ee128e95faec422a16ef6d6b to your computer and use it in GitHub Desktop.
Save r00li/e3965849ee128e95faec422a16ef6d6b to your computer and use it in GitHub Desktop.
#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