main.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. /*
  2. GPIO pulse generator project for the STM32L031
  3. I2C:
  4. Write 0, <gpio cmd>
  5. */
  6. #include "stm32l031xx.h"
  7. #include "core_cm0plus.h"
  8. /*================================================*/
  9. /* forward declaration */
  10. void setGPIO( uint8_t n );
  11. void clearGPIO(void);
  12. /*================================================*/
  13. /* queue */
  14. #define GPIO_QUEUE_MAX 128
  15. uint8_t gpio_queue_mem[GPIO_QUEUE_MAX];
  16. uint8_t gpio_queue_start = 0;
  17. uint8_t gpio_queue_end = 0;
  18. /* this is called from the I2C interrupt procedures */
  19. void addCmdToGPIOQueue(uint8_t n)
  20. {
  21. uint8_t pos;
  22. pos = gpio_queue_end ;
  23. pos++;
  24. if ( pos >= GPIO_QUEUE_MAX )
  25. pos = 0;
  26. if ( pos == gpio_queue_start )
  27. return; // queue overflow
  28. gpio_queue_mem[gpio_queue_end] = n;
  29. gpio_queue_end = pos;
  30. }
  31. uint8_t isGPIOQueueEmpty(void)
  32. {
  33. if ( gpio_queue_start == gpio_queue_end )
  34. return 1;
  35. return 0;
  36. }
  37. /* get the next command in the queue, return 255 if the queue is empty */
  38. uint8_t getCmdFromGPIOQueue(void)
  39. {
  40. uint8_t r = gpio_queue_mem[gpio_queue_start];
  41. if ( isGPIOQueueEmpty() )
  42. return 255;
  43. return r;
  44. }
  45. void removeCmdFromGPIOQueue(void)
  46. {
  47. if ( isGPIOQueueEmpty() )
  48. return;
  49. __disable_irq();
  50. gpio_queue_start++;
  51. if ( gpio_queue_start >= GPIO_QUEUE_MAX )
  52. gpio_queue_start = 0;
  53. __enable_irq();
  54. }
  55. /*================================================*/
  56. /* GPIO output state machine */
  57. #define GPIO_STATE_IDLE 0
  58. #define GPIO_STATE_TURN_ON 1
  59. #define GPIO_STATE_WAIT_ON 2
  60. #define GPIO_STATE_OFF 3
  61. /* time is in ticks + 1 */
  62. #define GPIO_STATE_ON_TICKS 0
  63. #define GPIO_STATE_OFF_TICKS 4
  64. volatile uint8_t gpio_state = GPIO_STATE_IDLE;
  65. volatile uint8_t gpio_state_machine_output_number = 0;
  66. volatile uint8_t gpio_state_machine_counter = 0;
  67. void gpioNextState(void)
  68. {
  69. switch(gpio_state)
  70. {
  71. case GPIO_STATE_IDLE:
  72. break;
  73. case GPIO_STATE_TURN_ON:
  74. setGPIO(gpio_state_machine_output_number);
  75. gpio_state_machine_counter = GPIO_STATE_ON_TICKS;
  76. gpio_state = GPIO_STATE_WAIT_ON;
  77. break;
  78. case GPIO_STATE_WAIT_ON:
  79. if ( gpio_state_machine_counter == 0 )
  80. {
  81. clearGPIO();
  82. gpio_state_machine_counter = GPIO_STATE_OFF_TICKS;
  83. gpio_state = GPIO_STATE_OFF;
  84. }
  85. else
  86. {
  87. gpio_state_machine_counter--;
  88. }
  89. break;
  90. case GPIO_STATE_OFF:
  91. if ( gpio_state_machine_counter == 0 )
  92. {
  93. gpio_state = GPIO_STATE_IDLE;
  94. }
  95. else
  96. {
  97. gpio_state_machine_counter--;
  98. }
  99. break;
  100. default:
  101. gpio_state = GPIO_STATE_IDLE;
  102. break;
  103. }
  104. }
  105. uint8_t gpioStartStateMachine(uint8_t gpio_number)
  106. {
  107. /* can we enable the state machine? */
  108. if ( gpio_state != GPIO_STATE_IDLE )
  109. return 0; /* not idle, can not start */
  110. /* set the gpio number */
  111. __disable_irq();
  112. gpio_state_machine_output_number = gpio_number;
  113. gpio_state = GPIO_STATE_TURN_ON;
  114. __enable_irq();
  115. return 1;
  116. }
  117. /*================================================*/
  118. /* Queue & State Machine Connector */
  119. void processQueue(void)
  120. {
  121. uint8_t cmd;
  122. cmd = getCmdFromGPIOQueue();
  123. if ( cmd < 255 )
  124. {
  125. /* try to start the state machine */
  126. if ( gpioStartStateMachine(cmd) != 0 )
  127. {
  128. /* success, remove the cmd from the queue */
  129. removeCmdFromGPIOQueue();
  130. }
  131. }
  132. }
  133. /*==============================================*/
  134. /* I2C */
  135. volatile unsigned char i2c_mem[256]; /* contains data, which read or written */
  136. volatile unsigned char i2c_idx; /* the current index into i2c_mem */
  137. volatile unsigned char i2c_is_write_idx; /* write state */
  138. volatile uint16_t i2c_total_irq_cnt;
  139. volatile uint16_t i2c_TXIS_cnt;
  140. volatile uint16_t i2c_RXNE_cnt;
  141. void i2c_mem_reset_write(void)
  142. {
  143. i2c_is_write_idx = 1;
  144. }
  145. void i2c_mem_init(void)
  146. {
  147. i2c_idx = 0;
  148. i2c_mem_reset_write();
  149. }
  150. void i2c_mem_set_index(unsigned char value)
  151. {
  152. i2c_idx = value;
  153. i2c_is_write_idx = 0;
  154. }
  155. void i2c_mem_write_via_index(unsigned char value)
  156. {
  157. if ( i2c_idx == 0 )
  158. {
  159. /* additionall put this byte into the queue */
  160. addCmdToGPIOQueue(value);
  161. }
  162. i2c_mem[i2c_idx++] = value;
  163. }
  164. unsigned char i2c_mem_read(void)
  165. {
  166. i2c_mem_reset_write();
  167. i2c_idx++;
  168. return i2c_mem[i2c_idx];
  169. }
  170. void i2c_mem_write(unsigned char value)
  171. {
  172. if ( i2c_is_write_idx != 0 )
  173. {
  174. i2c_mem_set_index(value);
  175. }
  176. else
  177. {
  178. i2c_is_write_idx = 0;
  179. i2c_mem_write_via_index(value);
  180. }
  181. }
  182. /* address: I2C address multiplied by 2 */
  183. /* Pins PA9 (SCL) and PA10 (SDA) */
  184. void i2c_hw_init(unsigned char address)
  185. {
  186. RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; /* Enable clock for I2C */
  187. RCC->IOPENR |= RCC_IOPENR_IOPAEN; /* Enable clock for GPIO Port A */
  188. __NOP(); /* extra delay for clock stabilization required? */
  189. __NOP();
  190. /* configure io */
  191. GPIOA->MODER &= ~GPIO_MODER_MODE9; /* clear mode for PA9 */
  192. GPIOA->MODER |= GPIO_MODER_MODE9_1; /* alt fn */
  193. GPIOA->OTYPER |= GPIO_OTYPER_OT_9; /* open drain */
  194. GPIOA->AFR[1] &= ~(15<<4); /* Clear Alternate Function PA9 */
  195. GPIOA->AFR[1] |= 1<<4; /* I2C Alternate Function PA9 */
  196. GPIOA->MODER &= ~GPIO_MODER_MODE10; /* clear mode for PA10 */
  197. GPIOA->MODER |= GPIO_MODER_MODE10_1; /* alt fn */
  198. GPIOA->OTYPER |= GPIO_OTYPER_OT_10; /* open drain */
  199. GPIOA->AFR[1] &= ~(15<<8); /* Clear Alternate Function PA10 */
  200. GPIOA->AFR[1] |= 1<<8; /* I2C Alternate Function PA10 */
  201. RCC->CCIPR &= ~RCC_CCIPR_I2C1SEL; /* write 00 to the I2C clk selection register */
  202. RCC->CCIPR |= RCC_CCIPR_I2C1SEL_0; /* select system clock (01) */
  203. /* I2C init flow chart: Clear PE bit */
  204. I2C1->CR1 &= ~I2C_CR1_PE;
  205. /* I2C init flow chart: Configure filter */
  206. /* leave at defaults */
  207. /* I2C init flow chart: Configure timing */
  208. /*
  209. standard mode 100kHz configuration
  210. SYSCLK = I2CCLK = 32 MHz
  211. PRESC = 6 bits 28..31
  212. SCLL = 0x13 bits 0..7
  213. SCLH = 0x0f bits 8..15
  214. SDADEL = 0x02 bits 16..19
  215. SCLDEL = 0x04 bits 20..23
  216. */
  217. I2C1->TIMINGR = 0x60420f13;
  218. /* I2C init flow chart: Configure NOSTRECH */
  219. I2C1->CR1 |= I2C_CR1_NOSTRETCH;
  220. /* I2C init flow chart: Enable I2C */
  221. I2C1->CR1 |= I2C_CR1_PE;
  222. /* disable OAR1 for reconfiguration */
  223. I2C1->OAR1 &= ~I2C_OAR1_OA1EN;
  224. I2C1->OAR1 = address;
  225. I2C1->OAR1 |= I2C_OAR1_OA1EN;
  226. /* enable interrupts */
  227. I2C1->CR1 |= I2C_CR1_STOPIE;
  228. I2C1->CR1 |= I2C_CR1_NACKIE;
  229. //I2C1->CR1 |= I2C_CR1_ADDRIE;
  230. I2C1->CR1 |= I2C_CR1_RXIE;
  231. I2C1->CR1 |= I2C_CR1_TXIE;
  232. /* load first value into TXDR register */
  233. I2C1->TXDR = i2c_mem[i2c_idx];
  234. /* enable IRQ in NVIC */
  235. NVIC_SetPriority(I2C1_IRQn, 0);
  236. NVIC_EnableIRQ(I2C1_IRQn);
  237. }
  238. void i2c_init(unsigned char address)
  239. {
  240. i2c_mem_init();
  241. i2c_hw_init(address);
  242. }
  243. void __attribute__ ((interrupt, used)) I2C1_IRQHandler(void)
  244. {
  245. unsigned long isr = I2C1->ISR;
  246. i2c_total_irq_cnt ++;
  247. if ( isr & I2C_ISR_TXIS )
  248. {
  249. i2c_TXIS_cnt++;
  250. I2C1->TXDR = i2c_mem_read();
  251. }
  252. else if ( isr & I2C_ISR_RXNE )
  253. {
  254. i2c_RXNE_cnt++;
  255. i2c_mem_write(I2C1->RXDR);
  256. I2C1->ISR |= I2C_ISR_TXE; // allow overwriting the TCDR with new data
  257. I2C1->TXDR = i2c_mem[i2c_idx];
  258. }
  259. else if ( isr & I2C_ISR_STOPF )
  260. {
  261. I2C1->ICR = I2C_ICR_STOPCF;
  262. I2C1->ISR |= I2C_ISR_TXE; // allow overwriting the TCDR with new data
  263. I2C1->TXDR = i2c_mem[i2c_idx];
  264. i2c_mem_reset_write();
  265. }
  266. else if ( isr & I2C_ISR_NACKF )
  267. {
  268. I2C1->ICR = I2C_ICR_NACKCF;
  269. I2C1->ISR |= I2C_ISR_TXE; // allow overwriting the TCDR with new data
  270. I2C1->TXDR = i2c_mem[i2c_idx];
  271. i2c_mem_reset_write();
  272. }
  273. else if ( isr & I2C_ISR_ADDR )
  274. {
  275. /* not required, the addr match interrupt is not enabled */
  276. I2C1->ICR = I2C_ICR_ADDRCF;
  277. I2C1->ISR |= I2C_ISR_TXE; // allow overwriting the TCDR with new data
  278. I2C1->TXDR = i2c_mem[i2c_idx];
  279. i2c_mem_reset_write();
  280. }
  281. /* if at any time the addr match is set, clear the flag */
  282. /* not sure, whether this is required */
  283. if ( isr & I2C_ISR_ADDR )
  284. {
  285. I2C1->ICR = I2C_ICR_ADDRCF;
  286. }
  287. }
  288. /*================================================*/
  289. volatile unsigned long SysTickCount = 0;
  290. void __attribute__ ((interrupt, used)) SysTick_Handler(void)
  291. {
  292. SysTickCount++;
  293. gpioNextState();
  294. }
  295. /*
  296. Delay by the provided number of system ticks.
  297. The delay must be smaller than the RELOAD value.
  298. This delay has an imprecision of about +/- 20 system ticks.
  299. */
  300. static void _delay_system_ticks_sub(uint32_t sys_ticks)
  301. {
  302. uint32_t start_val, end_val, curr_val;
  303. uint32_t load;
  304. start_val = SysTick->VAL;
  305. start_val &= 0x0ffffffUL;
  306. end_val = start_val;
  307. if ( end_val < sys_ticks )
  308. {
  309. /* check, if the operation after this if clause would lead to a negative result */
  310. /* if this would be the case, then add the reload value first */
  311. load = SysTick->LOAD;
  312. load &= 0x0ffffffUL;
  313. end_val += load;
  314. }
  315. /* counter goes towards zero, so end_val is below start value */
  316. end_val -= sys_ticks;
  317. /* wait until interval is left */
  318. if ( start_val >= end_val )
  319. {
  320. for(;;)
  321. {
  322. curr_val = SysTick->VAL;
  323. curr_val &= 0x0ffffffUL;
  324. if ( curr_val <= end_val )
  325. break;
  326. if ( curr_val > start_val )
  327. break;
  328. }
  329. }
  330. else
  331. {
  332. for(;;)
  333. {
  334. curr_val = SysTick->VAL;
  335. curr_val &= 0x0ffffffUL;
  336. if ( curr_val <= end_val && curr_val > start_val )
  337. break;
  338. }
  339. }
  340. }
  341. /*
  342. Delay by the provided number of system ticks.
  343. Any values between 0 and 0x0ffffffff are allowed.
  344. */
  345. void delay_system_ticks(uint32_t sys_ticks)
  346. {
  347. uint32_t load4;
  348. load4 = SysTick->LOAD;
  349. load4 &= 0x0ffffffUL;
  350. load4 >>= 2;
  351. while ( sys_ticks > load4 )
  352. {
  353. sys_ticks -= load4;
  354. _delay_system_ticks_sub(load4);
  355. }
  356. _delay_system_ticks_sub(sys_ticks);
  357. }
  358. void setHSIClock()
  359. {
  360. /* test if the current clock source is something else than HSI */
  361. if ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
  362. {
  363. /* enable HSI */
  364. RCC->CR |= RCC_CR_HSION;
  365. /* wait until HSI becomes ready */
  366. while ( (RCC->CR & RCC_CR_HSIRDY) == 0 )
  367. ;
  368. /* enable the HSI "divide by 4" bit */
  369. RCC->CR |= (uint32_t)(RCC_CR_HSIDIVEN);
  370. /* wait until the "divide by 4" flag is enabled */
  371. while((RCC->CR & RCC_CR_HSIDIVF) == 0)
  372. ;
  373. /* then use the HSI clock */
  374. RCC->CFGR = (RCC->CFGR & (uint32_t) (~RCC_CFGR_SW)) | RCC_CFGR_SW_HSI;
  375. /* wait until HSI clock is used */
  376. while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
  377. ;
  378. }
  379. /* disable PLL */
  380. RCC->CR &= (uint32_t)(~RCC_CR_PLLON);
  381. /* wait until PLL is inactive */
  382. while((RCC->CR & RCC_CR_PLLRDY) != 0)
  383. ;
  384. /* set latency to 1 wait state */
  385. FLASH->ACR |= FLASH_ACR_LATENCY;
  386. /* At this point the HSI runs with 4 MHz */
  387. /* Multiply by 16 device by 2 --> 32 MHz */
  388. RCC->CFGR = (RCC->CFGR & (~(RCC_CFGR_PLLMUL| RCC_CFGR_PLLDIV ))) | (RCC_CFGR_PLLMUL16 | RCC_CFGR_PLLDIV2);
  389. /* enable PLL */
  390. RCC->CR |= RCC_CR_PLLON;
  391. /* wait until the PLL is ready */
  392. while ((RCC->CR & RCC_CR_PLLRDY) == 0)
  393. ;
  394. /* use the PLL has clock source */
  395. RCC->CFGR |= (uint32_t) (RCC_CFGR_SW_PLL);
  396. /* wait until the PLL source is active */
  397. while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
  398. ;
  399. }
  400. void initGPIO(void)
  401. {
  402. RCC->IOPENR |= RCC_IOPENR_IOPAEN; /* Enable clock for GPIO Port A */
  403. __NOP();
  404. __NOP();
  405. GPIOA->MODER &= ~GPIO_MODER_MODE14; /* clear mode */
  406. GPIOA->MODER |= GPIO_MODER_MODE14_0; /* Output mode */
  407. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_14; /* no Push/Pull */
  408. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED14; /* low speed */
  409. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD14; /* no pullup/pulldown */
  410. GPIOA->BSRR = GPIO_BSRR_BR_14; /* atomic clr */
  411. GPIOA->MODER &= ~GPIO_MODER_MODE13; /* clear mode */
  412. GPIOA->MODER |= GPIO_MODER_MODE13_0; /* Output mode */
  413. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_13; /* no Push/Pull */
  414. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED13; /* low speed */
  415. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD13; /* no pullup/pulldown */
  416. GPIOA->BSRR = GPIO_BSRR_BR_13; /* atomic clr */
  417. GPIOA->MODER &= ~GPIO_MODER_MODE7; /* clear mode */
  418. GPIOA->MODER |= GPIO_MODER_MODE7_0; /* Output mode */
  419. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_7; /* no Push/Pull */
  420. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED7; /* low speed */
  421. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD7; /* no pullup/pulldown */
  422. GPIOA->BSRR = GPIO_BSRR_BR_7; /* atomic clr */
  423. GPIOA->MODER &= ~GPIO_MODER_MODE6; /* clear mode */
  424. GPIOA->MODER |= GPIO_MODER_MODE6_0; /* Output mode */
  425. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_6; /* no Push/Pull */
  426. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED6; /* low speed */
  427. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD6; /* no pullup/pulldown */
  428. GPIOA->BSRR = GPIO_BSRR_BR_6; /* atomic clr */
  429. GPIOA->MODER &= ~GPIO_MODER_MODE5; /* clear mode */
  430. GPIOA->MODER |= GPIO_MODER_MODE5_0; /* Output mode */
  431. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_5; /* no Push/Pull */
  432. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED5; /* low speed */
  433. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD5; /* no pullup/pulldown */
  434. GPIOA->BSRR = GPIO_BSRR_BR_5; /* atomic clr */
  435. GPIOA->MODER &= ~GPIO_MODER_MODE4; /* clear mode */
  436. GPIOA->MODER |= GPIO_MODER_MODE4_0; /* Output mode */
  437. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_4; /* no Push/Pull */
  438. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED4; /* low speed */
  439. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD4; /* no pullup/pulldown */
  440. GPIOA->BSRR = GPIO_BSRR_BR_4; /* atomic clr */
  441. GPIOA->MODER &= ~GPIO_MODER_MODE1; /* clear mode */
  442. GPIOA->MODER |= GPIO_MODER_MODE1_0; /* Output mode */
  443. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_1; /* no Push/Pull */
  444. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED1; /* low speed */
  445. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD1; /* no pullup/pulldown */
  446. GPIOA->BSRR = GPIO_BSRR_BR_1; /* atomic clr */
  447. GPIOA->MODER &= ~GPIO_MODER_MODE0; /* clear mode */
  448. GPIOA->MODER |= GPIO_MODER_MODE0_0; /* Output mode */
  449. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_0; /* no Push/Pull */
  450. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED0; /* low speed */
  451. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD0; /* no pullup/pulldown */
  452. GPIOA->BSRR = GPIO_BSRR_BR_0; /* atomic clr */
  453. }
  454. void clearGPIO(void)
  455. {
  456. GPIOA->BSRR = GPIO_BSRR_BR_14
  457. | GPIO_BSRR_BR_13
  458. | GPIO_BSRR_BR_7
  459. | GPIO_BSRR_BR_6
  460. | GPIO_BSRR_BR_5
  461. | GPIO_BSRR_BR_4
  462. | GPIO_BSRR_BR_1
  463. | GPIO_BSRR_BR_0;
  464. }
  465. /*
  466. 0: PA14
  467. 1: PA13
  468. 2: PA7
  469. 3: PA6
  470. 4: PA5
  471. 5: PA4
  472. 6: PA1
  473. 7: PA0
  474. */
  475. void setGPIO( uint8_t n )
  476. {
  477. clearGPIO();
  478. switch(n)
  479. {
  480. case 0: GPIOA->BSRR = GPIO_BSRR_BS_14; break;
  481. case 1: GPIOA->BSRR = GPIO_BSRR_BS_13; break;
  482. case 2: GPIOA->BSRR = GPIO_BSRR_BS_7; break;
  483. case 3: GPIOA->BSRR = GPIO_BSRR_BS_6; break;
  484. case 4: GPIOA->BSRR = GPIO_BSRR_BS_5; break;
  485. case 5: GPIOA->BSRR = GPIO_BSRR_BS_4; break;
  486. case 6: GPIOA->BSRR = GPIO_BSRR_BS_1; break;
  487. case 7: GPIOA->BSRR = GPIO_BSRR_BS_0; break;
  488. }
  489. }
  490. void setAllGPIO(void)
  491. {
  492. GPIOA->BSRR = GPIO_BSRR_BS_14
  493. | GPIO_BSRR_BS_13
  494. | GPIO_BSRR_BS_7
  495. | GPIO_BSRR_BS_6
  496. | GPIO_BSRR_BS_5
  497. | GPIO_BSRR_BS_4
  498. | GPIO_BSRR_BS_1
  499. | GPIO_BSRR_BS_0;
  500. }
  501. int main()
  502. {
  503. uint8_t i;
  504. initGPIO();
  505. setHSIClock();
  506. i2c_init(2*17);
  507. SysTick->LOAD = 32000*100 - 1; // 100 ms
  508. SysTick->VAL = 0;
  509. SysTick->CTRL = 7; /* enable, generate interrupt (SysTick_Handler), do not divide by 2 */
  510. /*
  511. for(;;)
  512. {
  513. delay_system_ticks(32000*200);
  514. setGPIO(7);
  515. delay_system_ticks(32000*200);
  516. clearGPIO();
  517. }
  518. */
  519. for( i = 0; i < 8; i++ )
  520. addCmdToGPIOQueue(i);
  521. for(;;)
  522. {
  523. processQueue();
  524. }
  525. }