fork download
  1. #include <avr/interrupt.h>
  2. #include <avr/io.h>
  3. #include <stdint.h>
  4.  
  5. static volatile enum states {
  6. GREEN_NORTH,
  7. BLINKING_NORTH_ON_1,
  8. BLINKING_NORTH_OFF_1,
  9. BLINKING_NORTH_ON_2,
  10. BLINKING_NORTH_OFF_2,
  11. BLINKING_NORTH_ON_3,
  12. BLINKING_NORTH_OFF_3,
  13. YELLOW_NORTH,
  14. GREEN_SOUTH,
  15. BLINKING_SOUTH_ON_1,
  16. BLINKING_SOUTH_OFF_1,
  17. BLINKING_SOUTH_ON_2,
  18. BLINKING_SOUTH_OFF_2,
  19. BLINKING_SOUTH_ON_3,
  20. BLINKING_SOUTH_OFF_3,
  21. YELLOW_SOUTH,
  22. GREEN_EAST,
  23. BLINKING_EAST_ON_1,
  24. BLINKING_EAST_OFF_1,
  25. BLINKING_EAST_ON_2,
  26. BLINKING_EAST_OFF_2,
  27. BLINKING_EAST_ON_3,
  28. BLINKING_EAST_OFF_3,
  29. YELLOW_EAST,
  30. GREEN_WEST,
  31. BLINKING_WEST_ON_1,
  32. BLINKING_WEST_OFF_1,
  33. BLINKING_WEST_ON_2,
  34. BLINKING_WEST_OFF_2,
  35. BLINKING_WEST_ON_3,
  36. BLINKING_WEST_OFF_3,
  37. YELLOW_WEST,
  38. } current_state;
  39.  
  40. enum { TCNT0_MAX = 250, TCNT0_START = 256 - TCNT0_MAX };
  41. enum { ON_MS = 10000, BLINK_MS = 500, YELLOW_MS = 3000 };
  42. static const volatile uint32_t ticks = (1e-3 * (((double) F_CPU / 8.0) / ((double) TCNT0_MAX))) + 0.5;
  43. static volatile uint32_t t = 0;
  44. static volatile uint32_t overflows = 0;
  45.  
  46. static void set_north_green_led(void) {
  47. PORTA |= _BV(PA0);
  48. }
  49.  
  50. static void set_north_yellow_led(void) {
  51. PORTA |= _BV(PA1);
  52. }
  53.  
  54. static void set_north_red_led(void) {
  55. PORTA |= _BV(PA2);
  56. }
  57.  
  58. static void reset_north_green_led(void) {
  59. PORTA &= ~(_BV(PA0));
  60. }
  61.  
  62. static void reset_north_yellow_led(void) {
  63. PORTA &= ~(_BV(PA1));
  64. }
  65.  
  66. static void reset_north_red_led(void) {
  67. PORTA &= ~(_BV(PA2));
  68. }
  69.  
  70. static void set_south_green_led(void) {
  71. PORTA |= _BV(PA3);
  72. }
  73.  
  74. static void set_south_yellow_led(void) {
  75. PORTA |= _BV(PA4);
  76. }
  77.  
  78. static void set_south_red_led(void) {
  79. PORTA |= _BV(PA5);
  80. }
  81.  
  82. static void reset_south_green_led(void) {
  83. PORTA &= ~(_BV(PA3));
  84. }
  85.  
  86. static void reset_south_yellow_led(void) {
  87. PORTA &= ~(_BV(PA4));
  88. }
  89.  
  90. static void reset_south_red_led(void) {
  91. PORTA &= ~(_BV(PA5));
  92. }
  93.  
  94. static void set_east_green_led(void) {
  95. PORTA |= _BV(PA6);
  96. }
  97.  
  98. static void set_east_yellow_led(void) {
  99. PORTA |= _BV(PA7);
  100. }
  101.  
  102. static void set_east_red_led(void) {
  103. PORTB |= _BV(PB0);
  104. }
  105.  
  106. static void reset_east_green_led(void) {
  107. PORTA &= ~(_BV(PA6));
  108. }
  109.  
  110. static void reset_east_yellow_led(void) {
  111. PORTA &= ~(_BV(PA7));
  112. }
  113.  
  114. static void reset_east_red_led(void) {
  115. PORTB &= ~(_BV(PB0));
  116. }
  117.  
  118. static void set_west_green_led(void) {
  119. PORTB |= _BV(PB1);
  120. }
  121.  
  122. static void set_west_yellow_led(void) {
  123. PORTB |= _BV(PB2);
  124. }
  125.  
  126. static void set_west_red_led(void) {
  127. PORTB |= _BV(PB3);
  128. }
  129.  
  130. static void reset_west_green_led(void) {
  131. PORTB &= ~(_BV(PB1));
  132. }
  133.  
  134. static void reset_west_yellow_led(void) {
  135. PORTB &= ~(_BV(PB2));
  136. }
  137.  
  138. static void reset_west_red_led(void) {
  139. PORTB &= ~(_BV(PB3));
  140. }
  141.  
  142. static void set_north_off(void) {
  143. reset_north_green_led();
  144. reset_north_yellow_led();
  145. reset_north_red_led();
  146. }
  147.  
  148. static void set_north_green(void) {
  149. set_north_green_led();
  150. reset_north_yellow_led();
  151. reset_north_red_led();
  152. }
  153.  
  154. static void set_north_yellow(void) {
  155. reset_north_green_led();
  156. set_north_yellow_led();
  157. reset_north_red_led();
  158. }
  159.  
  160. static void set_north_red(void) {
  161. reset_north_green_led();
  162. reset_north_yellow_led();
  163. set_north_red_led();
  164. }
  165.  
  166. static void set_south_off(void) {
  167. reset_south_green_led();
  168. reset_south_yellow_led();
  169. reset_south_red_led();
  170. }
  171.  
  172. static void set_south_green(void) {
  173. set_south_green_led();
  174. reset_south_yellow_led();
  175. reset_south_red_led();
  176. }
  177.  
  178. static void set_south_yellow(void) {
  179. reset_south_green_led();
  180. set_south_yellow_led();
  181. reset_south_red_led();
  182. }
  183.  
  184. static void set_south_red(void) {
  185. reset_south_green_led();
  186. reset_south_yellow_led();
  187. set_south_red_led();
  188. }
  189.  
  190. static void set_east_off(void) {
  191. reset_east_green_led();
  192. reset_east_yellow_led();
  193. reset_east_red_led();
  194. }
  195.  
  196. static void set_east_green(void) {
  197. set_east_green_led();
  198. reset_east_yellow_led();
  199. reset_east_red_led();
  200. }
  201.  
  202. static void set_east_yellow(void) {
  203. reset_east_green_led();
  204. set_east_yellow_led();
  205. reset_east_red_led();
  206. }
  207.  
  208. static void set_east_red(void) {
  209. reset_east_green_led();
  210. reset_east_yellow_led();
  211. set_east_red_led();
  212. }
  213.  
  214. static void set_west_off(void) {
  215. reset_west_green_led();
  216. reset_west_yellow_led();
  217. reset_west_red_led();
  218. }
  219.  
  220. static void set_west_green(void) {
  221. set_west_green_led();
  222. reset_west_yellow_led();
  223. reset_west_red_led();
  224. }
  225.  
  226. static void set_west_yellow(void) {
  227. reset_west_green_led();
  228. set_west_yellow_led();
  229. reset_west_red_led();
  230. }
  231.  
  232. static void set_west_red(void) {
  233. reset_west_green_led();
  234. reset_west_yellow_led();
  235. set_west_red_led();
  236. }
  237.  
  238. static void wait_ms(uint32_t seconds) {
  239. t = seconds;
  240. TCCR0 |= (_BV(CS01));
  241. TCNT0 = TCNT0_START;
  242. }
  243.  
  244. static void next_state(void) {
  245. current_state = (current_state != YELLOW_WEST ? current_state + 1 : 0);
  246. }
  247.  
  248. ISR(TIMER0_OVF_vect) {
  249. if (++overflows >= ticks * t) {
  250. switch (current_state) {
  251. case GREEN_NORTH:
  252. wait_ms(BLINK_MS);
  253. break;
  254.  
  255. case BLINKING_NORTH_ON_1:
  256. wait_ms(BLINK_MS);
  257. break;
  258.  
  259. case BLINKING_NORTH_OFF_1:
  260. wait_ms(BLINK_MS);
  261. break;
  262.  
  263. case BLINKING_NORTH_ON_2:
  264. wait_ms(BLINK_MS);
  265. break;
  266.  
  267. case BLINKING_NORTH_OFF_2:
  268. wait_ms(BLINK_MS);
  269. break;
  270.  
  271. case BLINKING_NORTH_ON_3:
  272. wait_ms(BLINK_MS);
  273. break;
  274.  
  275. case BLINKING_NORTH_OFF_3:
  276. wait_ms(YELLOW_MS);
  277. break;
  278.  
  279. case YELLOW_NORTH:
  280. wait_ms(ON_MS);
  281. break;
  282.  
  283. case GREEN_SOUTH:
  284. wait_ms(BLINK_MS);
  285. break;
  286.  
  287. case BLINKING_SOUTH_ON_1:
  288. wait_ms(BLINK_MS);
  289. break;
  290.  
  291. case BLINKING_SOUTH_OFF_1:
  292. wait_ms(BLINK_MS);
  293. break;
  294.  
  295. case BLINKING_SOUTH_ON_2:
  296. wait_ms(BLINK_MS);
  297. break;
  298.  
  299. case BLINKING_SOUTH_OFF_2:
  300. wait_ms(BLINK_MS);
  301. break;
  302.  
  303. case BLINKING_SOUTH_ON_3:
  304. wait_ms(BLINK_MS);
  305. break;
  306.  
  307. case BLINKING_SOUTH_OFF_3:
  308. wait_ms(YELLOW_MS);
  309. break;
  310.  
  311. case YELLOW_SOUTH:
  312. wait_ms(ON_MS);
  313. break;
  314.  
  315. case GREEN_EAST:
  316. wait_ms(BLINK_MS);
  317. break;
  318.  
  319. case BLINKING_EAST_ON_1:
  320. wait_ms(BLINK_MS);
  321. break;
  322.  
  323. case BLINKING_EAST_OFF_1:
  324. wait_ms(BLINK_MS);
  325. break;
  326.  
  327. case BLINKING_EAST_ON_2:
  328. wait_ms(BLINK_MS);
  329. break;
  330.  
  331. case BLINKING_EAST_OFF_2:
  332. wait_ms(BLINK_MS);
  333. break;
  334.  
  335. case BLINKING_EAST_ON_3:
  336. wait_ms(BLINK_MS);
  337. break;
  338.  
  339. case BLINKING_EAST_OFF_3:
  340. wait_ms(YELLOW_MS);
  341. break;
  342.  
  343. case YELLOW_EAST:
  344. wait_ms(ON_MS);
  345. break;
  346.  
  347. case GREEN_WEST:
  348. wait_ms(BLINK_MS);
  349. break;
  350.  
  351. case BLINKING_WEST_ON_1:
  352. wait_ms(BLINK_MS);
  353. break;
  354.  
  355. case BLINKING_WEST_OFF_1:
  356. wait_ms(BLINK_MS);
  357. break;
  358.  
  359. case BLINKING_WEST_ON_2:
  360. wait_ms(BLINK_MS);
  361. break;
  362.  
  363. case BLINKING_WEST_OFF_2:
  364. wait_ms(BLINK_MS);
  365. break;
  366.  
  367. case BLINKING_WEST_ON_3:
  368. wait_ms(BLINK_MS);
  369. break;
  370.  
  371. case BLINKING_WEST_OFF_3:
  372. wait_ms(YELLOW_MS);
  373. break;
  374.  
  375. case YELLOW_WEST:
  376. wait_ms(ON_MS);
  377. break;
  378.  
  379. default:
  380. break;
  381. }
  382. overflows = 0;
  383. next_state();
  384. }
  385. TCNT0 = TCNT0_START;
  386. }
  387.  
  388. static void initialize_io_registers(void) {
  389. DDRA = 0xff;
  390. DDRB |= (_BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3));
  391. }
  392.  
  393. static void initialize_interrupt_registers(void) {
  394. TIMSK |= (_BV(TOIE0));
  395. sei();
  396. }
  397.  
  398. static void initialize_start_state(void) {
  399. current_state = GREEN_NORTH;
  400. wait_ms(ON_MS);
  401. }
  402.  
  403. int main(void) {
  404. initialize_io_registers();
  405. initialize_interrupt_registers();
  406. initialize_start_state();
  407. for (;;) {
  408. switch (current_state) {
  409. case GREEN_NORTH:
  410. set_north_green();
  411. set_south_red();
  412. set_east_red();
  413. set_west_red();
  414. break;
  415.  
  416. case BLINKING_NORTH_ON_1:
  417. set_north_green();
  418. set_south_red();
  419. set_east_red();
  420. set_west_red();
  421. break;
  422.  
  423. case BLINKING_NORTH_OFF_1:
  424. set_north_off();
  425. set_south_red();
  426. set_east_red();
  427. set_west_red();
  428. break;
  429.  
  430. case BLINKING_NORTH_ON_2:
  431. set_north_green();
  432. set_south_red();
  433. set_east_red();
  434. set_west_red();
  435. break;
  436.  
  437. case BLINKING_NORTH_OFF_2:
  438. set_north_off();
  439. set_south_red();
  440. set_east_red();
  441. set_west_red();
  442. break;
  443.  
  444. case BLINKING_NORTH_ON_3:
  445. set_north_green();
  446. set_south_red();
  447. set_east_red();
  448. set_west_red();
  449. break;
  450.  
  451. case BLINKING_NORTH_OFF_3:
  452. set_north_off();
  453. set_south_red();
  454. set_east_red();
  455. set_west_red();
  456. break;
  457.  
  458. case YELLOW_NORTH:
  459. set_north_yellow();
  460. set_south_red();
  461. set_east_red();
  462. set_west_red();
  463. break;
  464.  
  465. case GREEN_SOUTH:
  466. set_north_red();
  467. set_south_green();
  468. set_east_red();
  469. set_west_red();
  470. break;
  471.  
  472. case BLINKING_SOUTH_ON_1:
  473. set_north_red();
  474. set_south_green();
  475. set_east_red();
  476. set_west_red();
  477. break;
  478.  
  479. case BLINKING_SOUTH_OFF_1:
  480. set_north_red();
  481. set_south_off();
  482. set_east_red();
  483. set_west_red();
  484. break;
  485.  
  486. case BLINKING_SOUTH_ON_2:
  487. set_north_red();
  488. set_south_green();
  489. set_east_red();
  490. set_west_red();
  491. break;
  492.  
  493. case BLINKING_SOUTH_OFF_2:
  494. set_north_red();
  495. set_south_off();
  496. set_east_red();
  497. set_west_red();
  498. break;
  499.  
  500. case BLINKING_SOUTH_ON_3:
  501. set_north_red();
  502. set_south_green();
  503. set_east_red();
  504. set_west_red();
  505. break;
  506.  
  507. case BLINKING_SOUTH_OFF_3:
  508. set_north_red();
  509. set_south_off();
  510. set_east_red();
  511. set_west_red();
  512. break;
  513.  
  514. case YELLOW_SOUTH:
  515. set_north_red();
  516. set_south_yellow();
  517. set_east_red();
  518. set_west_red();
  519. break;
  520.  
  521. case GREEN_EAST:
  522. set_north_red();
  523. set_south_red();
  524. set_east_green();
  525. set_west_red();
  526. break;
  527.  
  528. case BLINKING_EAST_ON_1:
  529. set_north_red();
  530. set_south_red();
  531. set_east_green();
  532. set_west_red();
  533. break;
  534.  
  535. case BLINKING_EAST_OFF_1:
  536. set_north_red();
  537. set_south_red();
  538. set_east_off();
  539. set_west_red();
  540. break;
  541.  
  542. case BLINKING_EAST_ON_2:
  543. set_north_red();
  544. set_south_red();
  545. set_east_green();
  546. set_west_red();
  547. break;
  548.  
  549. case BLINKING_EAST_OFF_2:
  550. set_north_red();
  551. set_south_red();
  552. set_east_off();
  553. set_west_red();
  554. break;
  555.  
  556. case BLINKING_EAST_ON_3:
  557. set_north_red();
  558. set_south_red();
  559. set_east_green();
  560. set_west_red();
  561. break;
  562.  
  563. case BLINKING_EAST_OFF_3:
  564. set_north_red();
  565. set_south_red();
  566. set_east_off();
  567. set_west_red();
  568. break;
  569.  
  570. case YELLOW_EAST:
  571. set_north_red();
  572. set_south_red();
  573. set_east_yellow();
  574. set_west_red();
  575. break;
  576.  
  577. case GREEN_WEST:
  578. set_north_red();
  579. set_south_red();
  580. set_east_red();
  581. set_west_green();
  582. break;
  583.  
  584. case BLINKING_WEST_ON_1:
  585. set_north_red();
  586. set_south_red();
  587. set_east_red();
  588. set_west_green();
  589. break;
  590.  
  591. case BLINKING_WEST_OFF_1:
  592. set_north_red();
  593. set_south_red();
  594. set_east_red();
  595. set_west_off();
  596. break;
  597.  
  598. case BLINKING_WEST_ON_2:
  599. set_north_red();
  600. set_south_red();
  601. set_east_red();
  602. set_west_green();
  603. break;
  604.  
  605. case BLINKING_WEST_OFF_2:
  606. set_north_red();
  607. set_south_red();
  608. set_east_red();
  609. set_west_off();
  610. break;
  611.  
  612. case BLINKING_WEST_ON_3:
  613. set_north_red();
  614. set_south_red();
  615. set_east_red();
  616. set_west_green();
  617. break;
  618.  
  619. case BLINKING_WEST_OFF_3:
  620. set_north_red();
  621. set_south_red();
  622. set_east_red();
  623. set_west_off();
  624. break;
  625.  
  626. case YELLOW_WEST:
  627. set_north_red();
  628. set_south_red();
  629. set_east_red();
  630. set_west_yellow();
  631. break;
  632.  
  633. default:
  634. break;
  635. }
  636. }
  637. return 0;
  638. }
  639.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty