Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: STM32F3-Discovery
neopixel.c@0:d89511b21e3d, 2016-05-25 (annotated)
- Committer:
- MartinJohnson
- Date:
- Wed May 25 23:54:30 2016 +0000
- Revision:
- 0:d89511b21e3d
initial commit
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| MartinJohnson | 0:d89511b21e3d | 1 | |
| MartinJohnson | 0:d89511b21e3d | 2 | #include <stm32f30x.h> |
| MartinJohnson | 0:d89511b21e3d | 3 | //#include <stm32f30x_misc.h> |
| MartinJohnson | 0:d89511b21e3d | 4 | //#define ARM_MATH_CM4 |
| MartinJohnson | 0:d89511b21e3d | 5 | #include <math.h> |
| MartinJohnson | 0:d89511b21e3d | 6 | #include "stm32f3_discovery_lsm303dlhc.h" |
| MartinJohnson | 0:d89511b21e3d | 7 | #include <stdlib.h> |
| MartinJohnson | 0:d89511b21e3d | 8 | |
| MartinJohnson | 0:d89511b21e3d | 9 | #define WS2812_GPIO GPIOB |
| MartinJohnson | 0:d89511b21e3d | 10 | #define WS2812_GPIO_AHB_PERIPHERAL RCC_AHBPeriph_GPIOB |
| MartinJohnson | 0:d89511b21e3d | 11 | #define WS2812_GPIO_AF GPIO_AF_1 |
| MartinJohnson | 0:d89511b21e3d | 12 | #define WS2812_PIN GPIO_Pin_8 // TIM16_CH1 |
| MartinJohnson | 0:d89511b21e3d | 13 | #define WS2812_PIN_SOURCE GPIO_PinSource8 |
| MartinJohnson | 0:d89511b21e3d | 14 | #define WS2812_TIMER TIM16 |
| MartinJohnson | 0:d89511b21e3d | 15 | #define WS2812_TIMER_APB2_PERIPHERAL RCC_APB2Periph_TIM16 |
| MartinJohnson | 0:d89511b21e3d | 16 | #define WS2812_DMA_CHANNEL DMA1_Channel3 |
| MartinJohnson | 0:d89511b21e3d | 17 | #define WS2812_IRQ DMA1_Channel3_IRQn |
| MartinJohnson | 0:d89511b21e3d | 18 | #define WS2812_DMA_TC_FLAG DMA1_FLAG_TC3 |
| MartinJohnson | 0:d89511b21e3d | 19 | |
| MartinJohnson | 0:d89511b21e3d | 20 | #define PI 3.1415926f |
| MartinJohnson | 0:d89511b21e3d | 21 | |
| MartinJohnson | 0:d89511b21e3d | 22 | #define WS2812_LED_STRIP_LENGTH 60 |
| MartinJohnson | 0:d89511b21e3d | 23 | #define WS2812_BITS_PER_LED 24 |
| MartinJohnson | 0:d89511b21e3d | 24 | #define WS2812_DELAY_BUFFER_LENGTH 42 // for 50us delay |
| MartinJohnson | 0:d89511b21e3d | 25 | |
| MartinJohnson | 0:d89511b21e3d | 26 | #define BIT_COMPARE_1 17 // timer compare value for logical 1 |
| MartinJohnson | 0:d89511b21e3d | 27 | #define BIT_COMPARE_0 9 // timer compare value for logical 0 |
| MartinJohnson | 0:d89511b21e3d | 28 | #define WS2812_DATA_BUFFER_SIZE (WS2812_BITS_PER_LED * WS2812_LED_STRIP_LENGTH) |
| MartinJohnson | 0:d89511b21e3d | 29 | |
| MartinJohnson | 0:d89511b21e3d | 30 | #define WS2812_DMA_BUFFER_SIZE (WS2812_DATA_BUFFER_SIZE + WS2812_DELAY_BUFFER_LENGTH) // number of bytes needed is #LEDs * 24 bytes + 42 trailing bytes) |
| MartinJohnson | 0:d89511b21e3d | 31 | |
| MartinJohnson | 0:d89511b21e3d | 32 | static volatile uint8_t ledStripDMABuffer[WS2812_DMA_BUFFER_SIZE]; |
| MartinJohnson | 0:d89511b21e3d | 33 | |
| MartinJohnson | 0:d89511b21e3d | 34 | //static volatile uint8_t rgbData[WS2812_LED_STRIP_LENGTH*3]; |
| MartinJohnson | 0:d89511b21e3d | 35 | |
| MartinJohnson | 0:d89511b21e3d | 36 | static volatile uint8_t WS2812LedDataTransferInProgress = 0; |
| MartinJohnson | 0:d89511b21e3d | 37 | static uint16_t dmaBufferOffset; |
| MartinJohnson | 0:d89511b21e3d | 38 | static int16_t ledIndex; |
| MartinJohnson | 0:d89511b21e3d | 39 | |
| MartinJohnson | 0:d89511b21e3d | 40 | volatile unsigned sysTiming; |
| MartinJohnson | 0:d89511b21e3d | 41 | volatile unsigned sysTicks = 0; |
| MartinJohnson | 0:d89511b21e3d | 42 | |
| MartinJohnson | 0:d89511b21e3d | 43 | int sysInitSystemTimer(void) { |
| MartinJohnson | 0:d89511b21e3d | 44 | |
| MartinJohnson | 0:d89511b21e3d | 45 | if (SysTick_Config((SystemCoreClock / 1000) -1 )) { |
| MartinJohnson | 0:d89511b21e3d | 46 | return(0); |
| MartinJohnson | 0:d89511b21e3d | 47 | } |
| MartinJohnson | 0:d89511b21e3d | 48 | return(1); |
| MartinJohnson | 0:d89511b21e3d | 49 | } |
| MartinJohnson | 0:d89511b21e3d | 50 | void sysDelayMs(unsigned dly) { |
| MartinJohnson | 0:d89511b21e3d | 51 | |
| MartinJohnson | 0:d89511b21e3d | 52 | sysTiming = dly; |
| MartinJohnson | 0:d89511b21e3d | 53 | |
| MartinJohnson | 0:d89511b21e3d | 54 | while (sysTiming > 0) __wfi(); |
| MartinJohnson | 0:d89511b21e3d | 55 | |
| MartinJohnson | 0:d89511b21e3d | 56 | } |
| MartinJohnson | 0:d89511b21e3d | 57 | void SysTick_Handler(void) { |
| MartinJohnson | 0:d89511b21e3d | 58 | sysTicks++; |
| MartinJohnson | 0:d89511b21e3d | 59 | if (sysTiming > 0) --sysTiming; |
| MartinJohnson | 0:d89511b21e3d | 60 | } |
| MartinJohnson | 0:d89511b21e3d | 61 | |
| MartinJohnson | 0:d89511b21e3d | 62 | void AccelerometerConfig(void) |
| MartinJohnson | 0:d89511b21e3d | 63 | { |
| MartinJohnson | 0:d89511b21e3d | 64 | LSM303DLHCMag_InitTypeDef LSM303DLHC_InitStructure; |
| MartinJohnson | 0:d89511b21e3d | 65 | LSM303DLHCAcc_InitTypeDef LSM303DLHCAcc_InitStructure; |
| MartinJohnson | 0:d89511b21e3d | 66 | LSM303DLHCAcc_FilterConfigTypeDef LSM303DLHCFilter_InitStructure; |
| MartinJohnson | 0:d89511b21e3d | 67 | |
| MartinJohnson | 0:d89511b21e3d | 68 | /* Configure MEMS magnetometer main parameters: temp, working mode, full Scale and Data rate */ |
| MartinJohnson | 0:d89511b21e3d | 69 | LSM303DLHC_InitStructure.Temperature_Sensor = LSM303DLHC_TEMPSENSOR_DISABLE; |
| MartinJohnson | 0:d89511b21e3d | 70 | LSM303DLHC_InitStructure.MagOutput_DataRate =LSM303DLHC_ODR_30_HZ ; |
| MartinJohnson | 0:d89511b21e3d | 71 | LSM303DLHC_InitStructure.MagFull_Scale = LSM303DLHC_FS_8_1_GA; |
| MartinJohnson | 0:d89511b21e3d | 72 | LSM303DLHC_InitStructure.Working_Mode = LSM303DLHC_CONTINUOS_CONVERSION; |
| MartinJohnson | 0:d89511b21e3d | 73 | LSM303DLHC_MagInit(&LSM303DLHC_InitStructure); |
| MartinJohnson | 0:d89511b21e3d | 74 | |
| MartinJohnson | 0:d89511b21e3d | 75 | /* Fill the accelerometer structure */ |
| MartinJohnson | 0:d89511b21e3d | 76 | LSM303DLHCAcc_InitStructure.Power_Mode = LSM303DLHC_NORMAL_MODE; |
| MartinJohnson | 0:d89511b21e3d | 77 | LSM303DLHCAcc_InitStructure.AccOutput_DataRate = LSM303DLHC_ODR_50_HZ; |
| MartinJohnson | 0:d89511b21e3d | 78 | LSM303DLHCAcc_InitStructure.Axes_Enable= LSM303DLHC_AXES_ENABLE; |
| MartinJohnson | 0:d89511b21e3d | 79 | LSM303DLHCAcc_InitStructure.AccFull_Scale = LSM303DLHC_FULLSCALE_2G; |
| MartinJohnson | 0:d89511b21e3d | 80 | LSM303DLHCAcc_InitStructure.BlockData_Update = LSM303DLHC_BlockUpdate_Continous; |
| MartinJohnson | 0:d89511b21e3d | 81 | LSM303DLHCAcc_InitStructure.Endianness=LSM303DLHC_BLE_LSB; |
| MartinJohnson | 0:d89511b21e3d | 82 | LSM303DLHCAcc_InitStructure.High_Resolution=LSM303DLHC_HR_ENABLE; |
| MartinJohnson | 0:d89511b21e3d | 83 | /* Configure the accelerometer main parameters */ |
| MartinJohnson | 0:d89511b21e3d | 84 | LSM303DLHC_AccInit(&LSM303DLHCAcc_InitStructure); |
| MartinJohnson | 0:d89511b21e3d | 85 | |
| MartinJohnson | 0:d89511b21e3d | 86 | /* Fill the accelerometer LPF structure */ |
| MartinJohnson | 0:d89511b21e3d | 87 | LSM303DLHCFilter_InitStructure.HighPassFilter_Mode_Selection =LSM303DLHC_HPM_NORMAL_MODE; |
| MartinJohnson | 0:d89511b21e3d | 88 | LSM303DLHCFilter_InitStructure.HighPassFilter_CutOff_Frequency = LSM303DLHC_HPFCF_16; |
| MartinJohnson | 0:d89511b21e3d | 89 | LSM303DLHCFilter_InitStructure.HighPassFilter_AOI1 = LSM303DLHC_HPF_AOI1_DISABLE; |
| MartinJohnson | 0:d89511b21e3d | 90 | LSM303DLHCFilter_InitStructure.HighPassFilter_AOI2 = LSM303DLHC_HPF_AOI2_DISABLE; |
| MartinJohnson | 0:d89511b21e3d | 91 | |
| MartinJohnson | 0:d89511b21e3d | 92 | /* Configure the accelerometer LPF main parameters */ |
| MartinJohnson | 0:d89511b21e3d | 93 | LSM303DLHC_AccFilterConfig(&LSM303DLHCFilter_InitStructure); |
| MartinJohnson | 0:d89511b21e3d | 94 | } |
| MartinJohnson | 0:d89511b21e3d | 95 | |
| MartinJohnson | 0:d89511b21e3d | 96 | void ReadAccelerometer(float * data) |
| MartinJohnson | 0:d89511b21e3d | 97 | { |
| MartinJohnson | 0:d89511b21e3d | 98 | uint8_t buffer[6]; |
| MartinJohnson | 0:d89511b21e3d | 99 | |
| MartinJohnson | 0:d89511b21e3d | 100 | LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_OUT_X_L_A, buffer, 6); |
| MartinJohnson | 0:d89511b21e3d | 101 | |
| MartinJohnson | 0:d89511b21e3d | 102 | for(int i=0; i<3; i++) { |
| MartinJohnson | 0:d89511b21e3d | 103 | data[i]=(float)((int16_t)((uint16_t)buffer[2*i+1] << 8) + buffer[2*i])/16; |
| MartinJohnson | 0:d89511b21e3d | 104 | } |
| MartinJohnson | 0:d89511b21e3d | 105 | } |
| MartinJohnson | 0:d89511b21e3d | 106 | |
| MartinJohnson | 0:d89511b21e3d | 107 | void ReadMagnetometer (float* pfData) |
| MartinJohnson | 0:d89511b21e3d | 108 | { |
| MartinJohnson | 0:d89511b21e3d | 109 | static uint8_t buffer[6] = {0}; |
| MartinJohnson | 0:d89511b21e3d | 110 | uint8_t CTRLB = 0; |
| MartinJohnson | 0:d89511b21e3d | 111 | uint16_t Magn_Sensitivity_XY = 0, Magn_Sensitivity_Z = 0; |
| MartinJohnson | 0:d89511b21e3d | 112 | uint8_t i =0; |
| MartinJohnson | 0:d89511b21e3d | 113 | LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_CRB_REG_M, &CTRLB, 1); |
| MartinJohnson | 0:d89511b21e3d | 114 | |
| MartinJohnson | 0:d89511b21e3d | 115 | LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_OUT_X_H_M, buffer, 1); |
| MartinJohnson | 0:d89511b21e3d | 116 | LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_OUT_X_L_M, buffer+1, 1); |
| MartinJohnson | 0:d89511b21e3d | 117 | LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_H_M, buffer+2, 1); |
| MartinJohnson | 0:d89511b21e3d | 118 | LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_L_M, buffer+3, 1); |
| MartinJohnson | 0:d89511b21e3d | 119 | LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_H_M, buffer+4, 1); |
| MartinJohnson | 0:d89511b21e3d | 120 | LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_L_M, buffer+5, 1); |
| MartinJohnson | 0:d89511b21e3d | 121 | /* Switch the sensitivity set in the CRTLB*/ |
| MartinJohnson | 0:d89511b21e3d | 122 | switch(CTRLB & 0xE0) |
| MartinJohnson | 0:d89511b21e3d | 123 | { |
| MartinJohnson | 0:d89511b21e3d | 124 | case LSM303DLHC_FS_1_3_GA: |
| MartinJohnson | 0:d89511b21e3d | 125 | Magn_Sensitivity_XY = LSM303DLHC_M_SENSITIVITY_XY_1_3Ga; |
| MartinJohnson | 0:d89511b21e3d | 126 | Magn_Sensitivity_Z = LSM303DLHC_M_SENSITIVITY_Z_1_3Ga; |
| MartinJohnson | 0:d89511b21e3d | 127 | break; |
| MartinJohnson | 0:d89511b21e3d | 128 | case LSM303DLHC_FS_1_9_GA: |
| MartinJohnson | 0:d89511b21e3d | 129 | Magn_Sensitivity_XY = LSM303DLHC_M_SENSITIVITY_XY_1_9Ga; |
| MartinJohnson | 0:d89511b21e3d | 130 | Magn_Sensitivity_Z = LSM303DLHC_M_SENSITIVITY_Z_1_9Ga; |
| MartinJohnson | 0:d89511b21e3d | 131 | break; |
| MartinJohnson | 0:d89511b21e3d | 132 | case LSM303DLHC_FS_2_5_GA: |
| MartinJohnson | 0:d89511b21e3d | 133 | Magn_Sensitivity_XY = LSM303DLHC_M_SENSITIVITY_XY_2_5Ga; |
| MartinJohnson | 0:d89511b21e3d | 134 | Magn_Sensitivity_Z = LSM303DLHC_M_SENSITIVITY_Z_2_5Ga; |
| MartinJohnson | 0:d89511b21e3d | 135 | break; |
| MartinJohnson | 0:d89511b21e3d | 136 | case LSM303DLHC_FS_4_0_GA: |
| MartinJohnson | 0:d89511b21e3d | 137 | Magn_Sensitivity_XY = LSM303DLHC_M_SENSITIVITY_XY_4Ga; |
| MartinJohnson | 0:d89511b21e3d | 138 | Magn_Sensitivity_Z = LSM303DLHC_M_SENSITIVITY_Z_4Ga; |
| MartinJohnson | 0:d89511b21e3d | 139 | break; |
| MartinJohnson | 0:d89511b21e3d | 140 | case LSM303DLHC_FS_4_7_GA: |
| MartinJohnson | 0:d89511b21e3d | 141 | Magn_Sensitivity_XY = LSM303DLHC_M_SENSITIVITY_XY_4_7Ga; |
| MartinJohnson | 0:d89511b21e3d | 142 | Magn_Sensitivity_Z = LSM303DLHC_M_SENSITIVITY_Z_4_7Ga; |
| MartinJohnson | 0:d89511b21e3d | 143 | break; |
| MartinJohnson | 0:d89511b21e3d | 144 | case LSM303DLHC_FS_5_6_GA: |
| MartinJohnson | 0:d89511b21e3d | 145 | Magn_Sensitivity_XY = LSM303DLHC_M_SENSITIVITY_XY_5_6Ga; |
| MartinJohnson | 0:d89511b21e3d | 146 | Magn_Sensitivity_Z = LSM303DLHC_M_SENSITIVITY_Z_5_6Ga; |
| MartinJohnson | 0:d89511b21e3d | 147 | break; |
| MartinJohnson | 0:d89511b21e3d | 148 | case LSM303DLHC_FS_8_1_GA: |
| MartinJohnson | 0:d89511b21e3d | 149 | Magn_Sensitivity_XY = LSM303DLHC_M_SENSITIVITY_XY_8_1Ga; |
| MartinJohnson | 0:d89511b21e3d | 150 | Magn_Sensitivity_Z = LSM303DLHC_M_SENSITIVITY_Z_8_1Ga; |
| MartinJohnson | 0:d89511b21e3d | 151 | break; |
| MartinJohnson | 0:d89511b21e3d | 152 | } |
| MartinJohnson | 0:d89511b21e3d | 153 | |
| MartinJohnson | 0:d89511b21e3d | 154 | for(i=0; i<2; i++) |
| MartinJohnson | 0:d89511b21e3d | 155 | { |
| MartinJohnson | 0:d89511b21e3d | 156 | pfData[i]=(float)((int16_t)(((uint16_t)buffer[2*i] << 8) + buffer[2*i+1])*1000)/Magn_Sensitivity_XY; |
| MartinJohnson | 0:d89511b21e3d | 157 | } |
| MartinJohnson | 0:d89511b21e3d | 158 | pfData[2]=(float)((int16_t)(((uint16_t)buffer[4] << 8) + buffer[5])*1000)/Magn_Sensitivity_Z; |
| MartinJohnson | 0:d89511b21e3d | 159 | } |
| MartinJohnson | 0:d89511b21e3d | 160 | |
| MartinJohnson | 0:d89511b21e3d | 161 | void GPIO_init(void) { |
| MartinJohnson | 0:d89511b21e3d | 162 | GPIO_InitTypeDef GPIO_InitStructure; |
| MartinJohnson | 0:d89511b21e3d | 163 | // GPIOA Periph clock enable |
| MartinJohnson | 0:d89511b21e3d | 164 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); |
| MartinJohnson | 0:d89511b21e3d | 165 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); |
| MartinJohnson | 0:d89511b21e3d | 166 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOE, ENABLE); |
| MartinJohnson | 0:d89511b21e3d | 167 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); |
| MartinJohnson | 0:d89511b21e3d | 168 | RCC_APB2PeriphClockCmd(WS2812_TIMER_APB2_PERIPHERAL, ENABLE); |
| MartinJohnson | 0:d89511b21e3d | 169 | |
| MartinJohnson | 0:d89511b21e3d | 170 | sysInitSystemTimer(); |
| MartinJohnson | 0:d89511b21e3d | 171 | /* Configuration alternate function push-pull */ |
| MartinJohnson | 0:d89511b21e3d | 172 | GPIO_StructInit(&GPIO_InitStructure); |
| MartinJohnson | 0:d89511b21e3d | 173 | GPIO_InitStructure.GPIO_Pin = WS2812_PIN; |
| MartinJohnson | 0:d89511b21e3d | 174 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; |
| MartinJohnson | 0:d89511b21e3d | 175 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; |
| MartinJohnson | 0:d89511b21e3d | 176 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; |
| MartinJohnson | 0:d89511b21e3d | 177 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
| MartinJohnson | 0:d89511b21e3d | 178 | GPIO_Init(WS2812_GPIO, &GPIO_InitStructure); |
| MartinJohnson | 0:d89511b21e3d | 179 | |
| MartinJohnson | 0:d89511b21e3d | 180 | GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_1); // pb8 is tim16 ch1 |
| MartinJohnson | 0:d89511b21e3d | 181 | |
| MartinJohnson | 0:d89511b21e3d | 182 | GPIO_InitStructure.GPIO_Pin = |
| MartinJohnson | 0:d89511b21e3d | 183 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | |
| MartinJohnson | 0:d89511b21e3d | 184 | GPIO_Pin_14 | GPIO_Pin_15; |
| MartinJohnson | 0:d89511b21e3d | 185 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; |
| MartinJohnson | 0:d89511b21e3d | 186 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; |
| MartinJohnson | 0:d89511b21e3d | 187 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; |
| MartinJohnson | 0:d89511b21e3d | 188 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
| MartinJohnson | 0:d89511b21e3d | 189 | GPIO_Init(GPIOE, &GPIO_InitStructure); |
| MartinJohnson | 0:d89511b21e3d | 190 | |
| MartinJohnson | 0:d89511b21e3d | 191 | GPIO_StructInit(&GPIO_InitStructure); |
| MartinJohnson | 0:d89511b21e3d | 192 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; |
| MartinJohnson | 0:d89511b21e3d | 193 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; |
| MartinJohnson | 0:d89511b21e3d | 194 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; |
| MartinJohnson | 0:d89511b21e3d | 195 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
| MartinJohnson | 0:d89511b21e3d | 196 | GPIO_Init(GPIOA, &GPIO_InitStructure); |
| MartinJohnson | 0:d89511b21e3d | 197 | |
| MartinJohnson | 0:d89511b21e3d | 198 | |
| MartinJohnson | 0:d89511b21e3d | 199 | GPIOE->ODR ^= 0x100; |
| MartinJohnson | 0:d89511b21e3d | 200 | } |
| MartinJohnson | 0:d89511b21e3d | 201 | |
| MartinJohnson | 0:d89511b21e3d | 202 | void TIM_init(void) |
| MartinJohnson | 0:d89511b21e3d | 203 | { |
| MartinJohnson | 0:d89511b21e3d | 204 | TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; |
| MartinJohnson | 0:d89511b21e3d | 205 | TIM_OCInitTypeDef TIM_OCInitStructure; |
| MartinJohnson | 0:d89511b21e3d | 206 | // NVIC_InitTypeDef NVIC_InitStructure; |
| MartinJohnson | 0:d89511b21e3d | 207 | uint16_t PrescalerValue; |
| MartinJohnson | 0:d89511b21e3d | 208 | |
| MartinJohnson | 0:d89511b21e3d | 209 | PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1; |
| MartinJohnson | 0:d89511b21e3d | 210 | /* Time base configuration */ |
| MartinJohnson | 0:d89511b21e3d | 211 | TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); |
| MartinJohnson | 0:d89511b21e3d | 212 | TIM_TimeBaseStructure.TIM_Period = 29; // 800kHz |
| MartinJohnson | 0:d89511b21e3d | 213 | TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; |
| MartinJohnson | 0:d89511b21e3d | 214 | TIM_TimeBaseStructure.TIM_ClockDivision = 0; |
| MartinJohnson | 0:d89511b21e3d | 215 | TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; |
| MartinJohnson | 0:d89511b21e3d | 216 | TIM_TimeBaseInit(WS2812_TIMER, &TIM_TimeBaseStructure); |
| MartinJohnson | 0:d89511b21e3d | 217 | |
| MartinJohnson | 0:d89511b21e3d | 218 | /* PWM1 Mode configuration */ |
| MartinJohnson | 0:d89511b21e3d | 219 | TIM_OCStructInit(&TIM_OCInitStructure); |
| MartinJohnson | 0:d89511b21e3d | 220 | TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; |
| MartinJohnson | 0:d89511b21e3d | 221 | TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; |
| MartinJohnson | 0:d89511b21e3d | 222 | TIM_OCInitStructure.TIM_Pulse = 0; |
| MartinJohnson | 0:d89511b21e3d | 223 | TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; |
| MartinJohnson | 0:d89511b21e3d | 224 | TIM_OC1Init(WS2812_TIMER, &TIM_OCInitStructure); |
| MartinJohnson | 0:d89511b21e3d | 225 | TIM_OC1PreloadConfig(WS2812_TIMER, TIM_OCPreload_Enable); |
| MartinJohnson | 0:d89511b21e3d | 226 | TIM_CtrlPWMOutputs(WS2812_TIMER, ENABLE); |
| MartinJohnson | 0:d89511b21e3d | 227 | } |
| MartinJohnson | 0:d89511b21e3d | 228 | |
| MartinJohnson | 0:d89511b21e3d | 229 | void DMA_init(void) { |
| MartinJohnson | 0:d89511b21e3d | 230 | DMA_InitTypeDef DMA_InitStructure; |
| MartinJohnson | 0:d89511b21e3d | 231 | /* configure DMA */ |
| MartinJohnson | 0:d89511b21e3d | 232 | /* DMA clock enable */ |
| MartinJohnson | 0:d89511b21e3d | 233 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); |
| MartinJohnson | 0:d89511b21e3d | 234 | /* DMA Channel Config */ |
| MartinJohnson | 0:d89511b21e3d | 235 | DMA_DeInit(WS2812_DMA_CHANNEL); |
| MartinJohnson | 0:d89511b21e3d | 236 | DMA_StructInit(&DMA_InitStructure); |
| MartinJohnson | 0:d89511b21e3d | 237 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & WS2812_TIMER->CCR1; |
| MartinJohnson | 0:d89511b21e3d | 238 | DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) ledStripDMABuffer; |
| MartinJohnson | 0:d89511b21e3d | 239 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; |
| MartinJohnson | 0:d89511b21e3d | 240 | DMA_InitStructure.DMA_BufferSize = WS2812_DMA_BUFFER_SIZE; |
| MartinJohnson | 0:d89511b21e3d | 241 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; |
| MartinJohnson | 0:d89511b21e3d | 242 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; |
| MartinJohnson | 0:d89511b21e3d | 243 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; |
| MartinJohnson | 0:d89511b21e3d | 244 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; |
| MartinJohnson | 0:d89511b21e3d | 245 | DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; |
| MartinJohnson | 0:d89511b21e3d | 246 | DMA_InitStructure.DMA_Priority = DMA_Priority_High; |
| MartinJohnson | 0:d89511b21e3d | 247 | DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; |
| MartinJohnson | 0:d89511b21e3d | 248 | DMA_Init(WS2812_DMA_CHANNEL, &DMA_InitStructure); |
| MartinJohnson | 0:d89511b21e3d | 249 | TIM_DMACmd(WS2812_TIMER, TIM_DMA_CC1, ENABLE); |
| MartinJohnson | 0:d89511b21e3d | 250 | DMA_ITConfig(WS2812_DMA_CHANNEL, DMA_IT_TC, ENABLE); |
| MartinJohnson | 0:d89511b21e3d | 251 | NVIC_InitTypeDef NVIC_InitStructure; |
| MartinJohnson | 0:d89511b21e3d | 252 | NVIC_InitStructure.NVIC_IRQChannel = WS2812_IRQ; |
| MartinJohnson | 0:d89511b21e3d | 253 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; |
| MartinJohnson | 0:d89511b21e3d | 254 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; |
| MartinJohnson | 0:d89511b21e3d | 255 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
| MartinJohnson | 0:d89511b21e3d | 256 | NVIC_Init(&NVIC_InitStructure); |
| MartinJohnson | 0:d89511b21e3d | 257 | } |
| MartinJohnson | 0:d89511b21e3d | 258 | |
| MartinJohnson | 0:d89511b21e3d | 259 | void WS2812LedStripDMAEnable(void) { |
| MartinJohnson | 0:d89511b21e3d | 260 | DMA_SetCurrDataCounter(WS2812_DMA_CHANNEL, |
| MartinJohnson | 0:d89511b21e3d | 261 | WS2812_DMA_BUFFER_SIZE); // load number of bytes to be transferred |
| MartinJohnson | 0:d89511b21e3d | 262 | TIM_SetCounter(WS2812_TIMER, 0); |
| MartinJohnson | 0:d89511b21e3d | 263 | TIM_Cmd(WS2812_TIMER, ENABLE); |
| MartinJohnson | 0:d89511b21e3d | 264 | DMA_Cmd(WS2812_DMA_CHANNEL, ENABLE); |
| MartinJohnson | 0:d89511b21e3d | 265 | } |
| MartinJohnson | 0:d89511b21e3d | 266 | |
| MartinJohnson | 0:d89511b21e3d | 267 | void DMA1_Channel3_IRQHandler(void) { |
| MartinJohnson | 0:d89511b21e3d | 268 | // GPIOE->ODR ^= 0x1000; |
| MartinJohnson | 0:d89511b21e3d | 269 | if (DMA_GetFlagStatus(WS2812_DMA_TC_FLAG)) { |
| MartinJohnson | 0:d89511b21e3d | 270 | WS2812LedDataTransferInProgress = 0; |
| MartinJohnson | 0:d89511b21e3d | 271 | DMA_Cmd(WS2812_DMA_CHANNEL, DISABLE); |
| MartinJohnson | 0:d89511b21e3d | 272 | DMA_ClearFlag(WS2812_DMA_TC_FLAG); |
| MartinJohnson | 0:d89511b21e3d | 273 | } |
| MartinJohnson | 0:d89511b21e3d | 274 | } |
| MartinJohnson | 0:d89511b21e3d | 275 | |
| MartinJohnson | 0:d89511b21e3d | 276 | void updateLEDDMABuffer(uint8_t componentValue) { |
| MartinJohnson | 0:d89511b21e3d | 277 | uint8_t bitIndex; |
| MartinJohnson | 0:d89511b21e3d | 278 | |
| MartinJohnson | 0:d89511b21e3d | 279 | for (bitIndex = 0; bitIndex < 8; bitIndex++) { |
| MartinJohnson | 0:d89511b21e3d | 280 | if ((componentValue << bitIndex) & |
| MartinJohnson | 0:d89511b21e3d | 281 | 0x80) // data sent MSB first, j = 0 is MSB j = 7 is LSB |
| MartinJohnson | 0:d89511b21e3d | 282 | { |
| MartinJohnson | 0:d89511b21e3d | 283 | ledStripDMABuffer[dmaBufferOffset] = BIT_COMPARE_1; |
| MartinJohnson | 0:d89511b21e3d | 284 | } |
| MartinJohnson | 0:d89511b21e3d | 285 | else { |
| MartinJohnson | 0:d89511b21e3d | 286 | ledStripDMABuffer[dmaBufferOffset] = BIT_COMPARE_0; // compare value for logical 0 |
| MartinJohnson | 0:d89511b21e3d | 287 | } |
| MartinJohnson | 0:d89511b21e3d | 288 | dmaBufferOffset++; |
| MartinJohnson | 0:d89511b21e3d | 289 | } |
| MartinJohnson | 0:d89511b21e3d | 290 | } |
| MartinJohnson | 0:d89511b21e3d | 291 | |
| MartinJohnson | 0:d89511b21e3d | 292 | typedef struct { |
| MartinJohnson | 0:d89511b21e3d | 293 | uint8_t red; |
| MartinJohnson | 0:d89511b21e3d | 294 | uint8_t green; |
| MartinJohnson | 0:d89511b21e3d | 295 | uint8_t blue; |
| MartinJohnson | 0:d89511b21e3d | 296 | } rgb_struct; |
| MartinJohnson | 0:d89511b21e3d | 297 | |
| MartinJohnson | 0:d89511b21e3d | 298 | static volatile rgb_struct rgbData[WS2812_LED_STRIP_LENGTH]; |
| MartinJohnson | 0:d89511b21e3d | 299 | |
| MartinJohnson | 0:d89511b21e3d | 300 | void WS2812UpdateStrip(void) { |
| MartinJohnson | 0:d89511b21e3d | 301 | static uint32_t waitCounter = 0; |
| MartinJohnson | 0:d89511b21e3d | 302 | |
| MartinJohnson | 0:d89511b21e3d | 303 | // wait until previous transfer completes |
| MartinJohnson | 0:d89511b21e3d | 304 | while (WS2812LedDataTransferInProgress) { |
| MartinJohnson | 0:d89511b21e3d | 305 | waitCounter++; |
| MartinJohnson | 0:d89511b21e3d | 306 | } |
| MartinJohnson | 0:d89511b21e3d | 307 | |
| MartinJohnson | 0:d89511b21e3d | 308 | dmaBufferOffset = 0; // reset buffer memory index |
| MartinJohnson | 0:d89511b21e3d | 309 | ledIndex = 0; // reset led index |
| MartinJohnson | 0:d89511b21e3d | 310 | |
| MartinJohnson | 0:d89511b21e3d | 311 | // fill transmit buffer with correct compare values to achieve |
| MartinJohnson | 0:d89511b21e3d | 312 | // correct pulse widths according to color values |
| MartinJohnson | 0:d89511b21e3d | 313 | while (ledIndex < WS2812_LED_STRIP_LENGTH) { |
| MartinJohnson | 0:d89511b21e3d | 314 | updateLEDDMABuffer(rgbData[ledIndex].green); |
| MartinJohnson | 0:d89511b21e3d | 315 | updateLEDDMABuffer(rgbData[ledIndex].red); |
| MartinJohnson | 0:d89511b21e3d | 316 | updateLEDDMABuffer(rgbData[ledIndex++].blue); |
| MartinJohnson | 0:d89511b21e3d | 317 | } |
| MartinJohnson | 0:d89511b21e3d | 318 | |
| MartinJohnson | 0:d89511b21e3d | 319 | WS2812LedDataTransferInProgress = 1; |
| MartinJohnson | 0:d89511b21e3d | 320 | WS2812LedStripDMAEnable(); |
| MartinJohnson | 0:d89511b21e3d | 321 | } |
| MartinJohnson | 0:d89511b21e3d | 322 | |
| MartinJohnson | 0:d89511b21e3d | 323 | extern volatile unsigned sysTicks; |
| MartinJohnson | 0:d89511b21e3d | 324 | int rndseed=0; |
| MartinJohnson | 0:d89511b21e3d | 325 | /* |
| MartinJohnson | 0:d89511b21e3d | 326 | void srand(int i) { |
| MartinJohnson | 0:d89511b21e3d | 327 | rndseed = i; |
| MartinJohnson | 0:d89511b21e3d | 328 | } |
| MartinJohnson | 0:d89511b21e3d | 329 | |
| MartinJohnson | 0:d89511b21e3d | 330 | |
| MartinJohnson | 0:d89511b21e3d | 331 | int rand() { |
| MartinJohnson | 0:d89511b21e3d | 332 | return (((rndseed = rndseed * 214013L + 2531011L) >> 16) & |
| MartinJohnson | 0:d89511b21e3d | 333 | 0x7fff); |
| MartinJohnson | 0:d89511b21e3d | 334 | } |
| MartinJohnson | 0:d89511b21e3d | 335 | */ |
| MartinJohnson | 0:d89511b21e3d | 336 | |
| MartinJohnson | 0:d89511b21e3d | 337 | void WS2812LedStripInit(void) { |
| MartinJohnson | 0:d89511b21e3d | 338 | int i; |
| MartinJohnson | 0:d89511b21e3d | 339 | for (i = 0; i < WS2812_DMA_BUFFER_SIZE; i++) |
| MartinJohnson | 0:d89511b21e3d | 340 | ledStripDMABuffer[i] = 0; |
| MartinJohnson | 0:d89511b21e3d | 341 | WS2812UpdateStrip(); |
| MartinJohnson | 0:d89511b21e3d | 342 | } |
| MartinJohnson | 0:d89511b21e3d | 343 | static float AccBuffer[3] = {0.0f}; |
| MartinJohnson | 0:d89511b21e3d | 344 | static float MagBuffer[3] = {0.0f}; |
| MartinJohnson | 0:d89511b21e3d | 345 | |
| MartinJohnson | 0:d89511b21e3d | 346 | //extern float arm_sqrt_f32(float f); |
| MartinJohnson | 0:d89511b21e3d | 347 | int getheading() { |
| MartinJohnson | 0:d89511b21e3d | 348 | /* Read Compass data */ |
| MartinJohnson | 0:d89511b21e3d | 349 | ReadMagnetometer(MagBuffer); |
| MartinJohnson | 0:d89511b21e3d | 350 | ReadAccelerometer(AccBuffer); |
| MartinJohnson | 0:d89511b21e3d | 351 | int i; |
| MartinJohnson | 0:d89511b21e3d | 352 | float fNormAcc, fSinRoll, fCosRoll, fSinPitch, fCosPitch = 0.0f, RollAng = 0.0f, PitchAng = 0.0f; |
| MartinJohnson | 0:d89511b21e3d | 353 | float fTiltedX, fTiltedY = 0.0f; |
| MartinJohnson | 0:d89511b21e3d | 354 | float HeadingValue; |
| MartinJohnson | 0:d89511b21e3d | 355 | |
| MartinJohnson | 0:d89511b21e3d | 356 | for (i = 0; i < 3; i++) |
| MartinJohnson | 0:d89511b21e3d | 357 | AccBuffer[i] /= 100.0f; |
| MartinJohnson | 0:d89511b21e3d | 358 | |
| MartinJohnson | 0:d89511b21e3d | 359 | fNormAcc = sqrtf((AccBuffer[0] * AccBuffer[0]) + (AccBuffer[1] * AccBuffer[1]) + |
| MartinJohnson | 0:d89511b21e3d | 360 | (AccBuffer[2] * AccBuffer[2])); |
| MartinJohnson | 0:d89511b21e3d | 361 | |
| MartinJohnson | 0:d89511b21e3d | 362 | fSinRoll = -AccBuffer[1] / fNormAcc; |
| MartinJohnson | 0:d89511b21e3d | 363 | fCosRoll = sqrtf(1.0f - (fSinRoll * fSinRoll)); |
| MartinJohnson | 0:d89511b21e3d | 364 | fSinPitch = AccBuffer[0] / fNormAcc; |
| MartinJohnson | 0:d89511b21e3d | 365 | fCosPitch = sqrtf(1.0f - (fSinPitch * fSinPitch)); |
| MartinJohnson | 0:d89511b21e3d | 366 | if (fSinRoll > 0) { |
| MartinJohnson | 0:d89511b21e3d | 367 | if (fCosRoll > 0) { |
| MartinJohnson | 0:d89511b21e3d | 368 | RollAng = acos(fCosRoll) * 180 / PI; |
| MartinJohnson | 0:d89511b21e3d | 369 | } |
| MartinJohnson | 0:d89511b21e3d | 370 | else { |
| MartinJohnson | 0:d89511b21e3d | 371 | RollAng = acos(fCosRoll) * 180 / PI + 180; |
| MartinJohnson | 0:d89511b21e3d | 372 | } |
| MartinJohnson | 0:d89511b21e3d | 373 | } |
| MartinJohnson | 0:d89511b21e3d | 374 | else { |
| MartinJohnson | 0:d89511b21e3d | 375 | if (fCosRoll > 0) { |
| MartinJohnson | 0:d89511b21e3d | 376 | RollAng = acos(fCosRoll) * 180 / PI + 360; |
| MartinJohnson | 0:d89511b21e3d | 377 | } |
| MartinJohnson | 0:d89511b21e3d | 378 | else { |
| MartinJohnson | 0:d89511b21e3d | 379 | RollAng = acos(fCosRoll) * 180 / PI + 180; |
| MartinJohnson | 0:d89511b21e3d | 380 | } |
| MartinJohnson | 0:d89511b21e3d | 381 | } |
| MartinJohnson | 0:d89511b21e3d | 382 | if (fSinPitch > 0) { |
| MartinJohnson | 0:d89511b21e3d | 383 | if (fCosPitch > 0) { |
| MartinJohnson | 0:d89511b21e3d | 384 | PitchAng = acos(fCosPitch) * 180 / PI; |
| MartinJohnson | 0:d89511b21e3d | 385 | } |
| MartinJohnson | 0:d89511b21e3d | 386 | else { |
| MartinJohnson | 0:d89511b21e3d | 387 | PitchAng = acos(fCosPitch) * 180 / PI + 180; |
| MartinJohnson | 0:d89511b21e3d | 388 | } |
| MartinJohnson | 0:d89511b21e3d | 389 | } |
| MartinJohnson | 0:d89511b21e3d | 390 | else { |
| MartinJohnson | 0:d89511b21e3d | 391 | if (fCosPitch > 0) { |
| MartinJohnson | 0:d89511b21e3d | 392 | PitchAng = acos(fCosPitch) * 180 / PI + 360; |
| MartinJohnson | 0:d89511b21e3d | 393 | } |
| MartinJohnson | 0:d89511b21e3d | 394 | else { |
| MartinJohnson | 0:d89511b21e3d | 395 | PitchAng = acos(fCosPitch) * 180 / PI + 180; |
| MartinJohnson | 0:d89511b21e3d | 396 | } |
| MartinJohnson | 0:d89511b21e3d | 397 | } |
| MartinJohnson | 0:d89511b21e3d | 398 | |
| MartinJohnson | 0:d89511b21e3d | 399 | if (RollAng >= 360) { |
| MartinJohnson | 0:d89511b21e3d | 400 | RollAng = RollAng - 360; |
| MartinJohnson | 0:d89511b21e3d | 401 | } |
| MartinJohnson | 0:d89511b21e3d | 402 | |
| MartinJohnson | 0:d89511b21e3d | 403 | if (PitchAng >= 360) { |
| MartinJohnson | 0:d89511b21e3d | 404 | PitchAng = PitchAng - 360; |
| MartinJohnson | 0:d89511b21e3d | 405 | } |
| MartinJohnson | 0:d89511b21e3d | 406 | |
| MartinJohnson | 0:d89511b21e3d | 407 | fTiltedX = MagBuffer[0] * fCosPitch + MagBuffer[2] * fSinPitch; |
| MartinJohnson | 0:d89511b21e3d | 408 | fTiltedY = MagBuffer[0] * fSinRoll * fSinPitch + MagBuffer[1] * fCosRoll - |
| MartinJohnson | 0:d89511b21e3d | 409 | MagBuffer[1] * fSinRoll * fCosPitch; |
| MartinJohnson | 0:d89511b21e3d | 410 | |
| MartinJohnson | 0:d89511b21e3d | 411 | // fTiltedX=fTiltedX/sqrt(fTiltedX*fTiltedX+fTiltedY*fTiltedY); |
| MartinJohnson | 0:d89511b21e3d | 412 | HeadingValue = (float) ((atan2f( (float)fTiltedY, (float)fTiltedX)) * 180) / PI; |
| MartinJohnson | 0:d89511b21e3d | 413 | |
| MartinJohnson | 0:d89511b21e3d | 414 | if (HeadingValue < 0) { |
| MartinJohnson | 0:d89511b21e3d | 415 | HeadingValue = HeadingValue + 360; |
| MartinJohnson | 0:d89511b21e3d | 416 | } |
| MartinJohnson | 0:d89511b21e3d | 417 | return HeadingValue; |
| MartinJohnson | 0:d89511b21e3d | 418 | |
| MartinJohnson | 0:d89511b21e3d | 419 | } |
| MartinJohnson | 0:d89511b21e3d | 420 | |
| MartinJohnson | 0:d89511b21e3d | 421 | int main(void) { |
| MartinJohnson | 0:d89511b21e3d | 422 | uint8_t i = 0; |
| MartinJohnson | 0:d89511b21e3d | 423 | int j=0; |
| MartinJohnson | 0:d89511b21e3d | 424 | int delay=2000; |
| MartinJohnson | 0:d89511b21e3d | 425 | int dch=-1; |
| MartinJohnson | 0:d89511b21e3d | 426 | int dir=1; |
| MartinJohnson | 0:d89511b21e3d | 427 | int btn=0; |
| MartinJohnson | 0:d89511b21e3d | 428 | uint32_t rgb = 0x0ff0000ff; |
| MartinJohnson | 0:d89511b21e3d | 429 | GPIO_init(); |
| MartinJohnson | 0:d89511b21e3d | 430 | GPIOE->ODR ^= 0x100; |
| MartinJohnson | 0:d89511b21e3d | 431 | DMA_init(); |
| MartinJohnson | 0:d89511b21e3d | 432 | GPIOE->ODR ^= 0x200; |
| MartinJohnson | 0:d89511b21e3d | 433 | TIM_init(); |
| MartinJohnson | 0:d89511b21e3d | 434 | AccelerometerConfig(); |
| MartinJohnson | 0:d89511b21e3d | 435 | |
| MartinJohnson | 0:d89511b21e3d | 436 | WS2812LedDataTransferInProgress = 0; |
| MartinJohnson | 0:d89511b21e3d | 437 | WS2812LedStripInit(); |
| MartinJohnson | 0:d89511b21e3d | 438 | btn=GPIOA->IDR; |
| MartinJohnson | 0:d89511b21e3d | 439 | if((GPIOA->IDR & 1)==1) { |
| MartinJohnson | 0:d89511b21e3d | 440 | // a giant compass! |
| MartinJohnson | 0:d89511b21e3d | 441 | while (1) { |
| MartinJohnson | 0:d89511b21e3d | 442 | int heading = getheading(); |
| MartinJohnson | 0:d89511b21e3d | 443 | int led = (heading * WS2812_LED_STRIP_LENGTH) / 360; |
| MartinJohnson | 0:d89511b21e3d | 444 | int next = (led + 1) % WS2812_LED_STRIP_LENGTH; |
| MartinJohnson | 0:d89511b21e3d | 445 | int v2 = (heading - (led * 360) / WS2812_LED_STRIP_LENGTH) * 10; |
| MartinJohnson | 0:d89511b21e3d | 446 | int v1 = 225 - v2; |
| MartinJohnson | 0:d89511b21e3d | 447 | |
| MartinJohnson | 0:d89511b21e3d | 448 | rgbData[led].red = v1; |
| MartinJohnson | 0:d89511b21e3d | 449 | rgbData[next].red = v2; |
| MartinJohnson | 0:d89511b21e3d | 450 | |
| MartinJohnson | 0:d89511b21e3d | 451 | WS2812UpdateStrip(); |
| MartinJohnson | 0:d89511b21e3d | 452 | // wait 5ms |
| MartinJohnson | 0:d89511b21e3d | 453 | sysDelayMs(15); |
| MartinJohnson | 0:d89511b21e3d | 454 | rgbData[led].red = 0; |
| MartinJohnson | 0:d89511b21e3d | 455 | rgbData[next].red = 0; |
| MartinJohnson | 0:d89511b21e3d | 456 | |
| MartinJohnson | 0:d89511b21e3d | 457 | } |
| MartinJohnson | 0:d89511b21e3d | 458 | } |
| MartinJohnson | 0:d89511b21e3d | 459 | while (1) { // flashing lights moving along the strip |
| MartinJohnson | 0:d89511b21e3d | 460 | rgbData[j].red = (rgb & 255); // green |
| MartinJohnson | 0:d89511b21e3d | 461 | rgbData[j].green = (rgb >> 8) & 255; // red |
| MartinJohnson | 0:d89511b21e3d | 462 | rgbData[j].blue = (rgb >> 16) & 255; // blue |
| MartinJohnson | 0:d89511b21e3d | 463 | |
| MartinJohnson | 0:d89511b21e3d | 464 | int NLIGHTS=4; |
| MartinJohnson | 0:d89511b21e3d | 465 | i=j; |
| MartinJohnson | 0:d89511b21e3d | 466 | for(int k=1;k<NLIGHTS;k++) { |
| MartinJohnson | 0:d89511b21e3d | 467 | i=(i+WS2812_LED_STRIP_LENGTH/NLIGHTS)%WS2812_LED_STRIP_LENGTH; |
| MartinJohnson | 0:d89511b21e3d | 468 | rgbData[i].red = (rgb & 255); // green |
| MartinJohnson | 0:d89511b21e3d | 469 | rgbData[i].green = (rgb >> 8) & 255; // red |
| MartinJohnson | 0:d89511b21e3d | 470 | rgbData[i].blue = (rgb >> 16) & 255; // blue |
| MartinJohnson | 0:d89511b21e3d | 471 | } |
| MartinJohnson | 0:d89511b21e3d | 472 | |
| MartinJohnson | 0:d89511b21e3d | 473 | WS2812UpdateStrip(); |
| MartinJohnson | 0:d89511b21e3d | 474 | sysDelayMs(delay/100); |
| MartinJohnson | 0:d89511b21e3d | 475 | if((GPIOA->IDR & 1)==1 && btn==0) |
| MartinJohnson | 0:d89511b21e3d | 476 | dir=-dir; |
| MartinJohnson | 0:d89511b21e3d | 477 | btn=(GPIOA->IDR & 1); |
| MartinJohnson | 0:d89511b21e3d | 478 | delay=delay+dch; |
| MartinJohnson | 0:d89511b21e3d | 479 | if(delay<500 || delay>3000) |
| MartinJohnson | 0:d89511b21e3d | 480 | dch=-dch; |
| MartinJohnson | 0:d89511b21e3d | 481 | for(int k=0;k<WS2812_LED_STRIP_LENGTH;k++) { |
| MartinJohnson | 0:d89511b21e3d | 482 | rgbData[k].red = 0; |
| MartinJohnson | 0:d89511b21e3d | 483 | rgbData[k].green = 0; |
| MartinJohnson | 0:d89511b21e3d | 484 | rgbData[k].blue = 0; |
| MartinJohnson | 0:d89511b21e3d | 485 | } |
| MartinJohnson | 0:d89511b21e3d | 486 | |
| MartinJohnson | 0:d89511b21e3d | 487 | ReadAccelerometer(AccBuffer); |
| MartinJohnson | 0:d89511b21e3d | 488 | int x=(int)AccBuffer[0]; |
| MartinJohnson | 0:d89511b21e3d | 489 | int y=(int)AccBuffer[1]; |
| MartinJohnson | 0:d89511b21e3d | 490 | int z=(int)AccBuffer[2]; |
| MartinJohnson | 0:d89511b21e3d | 491 | |
| MartinJohnson | 0:d89511b21e3d | 492 | delay=10000-abs(y)*20; |
| MartinJohnson | 0:d89511b21e3d | 493 | if(delay<0) delay=0; |
| MartinJohnson | 0:d89511b21e3d | 494 | if(y<0) |
| MartinJohnson | 0:d89511b21e3d | 495 | dir=1; |
| MartinJohnson | 0:d89511b21e3d | 496 | else |
| MartinJohnson | 0:d89511b21e3d | 497 | dir=-1; |
| MartinJohnson | 0:d89511b21e3d | 498 | |
| MartinJohnson | 0:d89511b21e3d | 499 | j=(j+dir+WS2812_LED_STRIP_LENGTH)%WS2812_LED_STRIP_LENGTH; |
| MartinJohnson | 0:d89511b21e3d | 500 | |
| MartinJohnson | 0:d89511b21e3d | 501 | rgb=(rgb<<1) /*^ (rand()&1 & rand()&1) ; */| (rgb>>24); |
| MartinJohnson | 0:d89511b21e3d | 502 | |
| MartinJohnson | 0:d89511b21e3d | 503 | } |
| MartinJohnson | 0:d89511b21e3d | 504 | } |
| MartinJohnson | 0:d89511b21e3d | 505 | |
| MartinJohnson | 0:d89511b21e3d | 506 |