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. }
  386.  
  387. static void initialize_io_registers(void) {
  388. DDRA = 0xff;
  389. DDRB |= (_BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3));
  390. }
  391.  
  392. static void initialize_interrupt_registers(void) {
  393. TIMSK |= (_BV(TOIE0));
  394. sei();
  395. }
  396.  
  397. static void initialize_start_state(void) {
  398. current_state = GREEN_NORTH;
  399. wait_ms(ON_MS);
  400. }
  401.  
  402. int main(void) {
  403. initialize_io_registers();
  404. initialize_interrupt_registers();
  405. initialize_start_state();
  406. for (;;) {
  407. switch (current_state) {
  408. case GREEN_NORTH:
  409. set_north_green();
  410. set_south_red();
  411. set_east_red();
  412. set_west_red();
  413. break;
  414.  
  415. case BLINKING_NORTH_ON_1:
  416. set_north_green();
  417. set_south_red();
  418. set_east_red();
  419. set_west_red();
  420. break;
  421.  
  422. case BLINKING_NORTH_OFF_1:
  423. set_north_off();
  424. set_south_red();
  425. set_east_red();
  426. set_west_red();
  427. break;
  428.  
  429. case BLINKING_NORTH_ON_2:
  430. set_north_green();
  431. set_south_red();
  432. set_east_red();
  433. set_west_red();
  434. break;
  435.  
  436. case BLINKING_NORTH_OFF_2:
  437. set_north_off();
  438. set_south_red();
  439. set_east_red();
  440. set_west_red();
  441. break;
  442.  
  443. case BLINKING_NORTH_ON_3:
  444. set_north_green();
  445. set_south_red();
  446. set_east_red();
  447. set_west_red();
  448. break;
  449.  
  450. case BLINKING_NORTH_OFF_3:
  451. set_north_off();
  452. set_south_red();
  453. set_east_red();
  454. set_west_red();
  455. break;
  456.  
  457. case YELLOW_NORTH:
  458. set_north_yellow();
  459. set_south_red();
  460. set_east_red();
  461. set_west_red();
  462. break;
  463.  
  464. case GREEN_SOUTH:
  465. set_north_red();
  466. set_south_green();
  467. set_east_red();
  468. set_west_red();
  469. break;
  470.  
  471. case BLINKING_SOUTH_ON_1:
  472. set_north_red();
  473. set_south_green();
  474. set_east_red();
  475. set_west_red();
  476. break;
  477.  
  478. case BLINKING_SOUTH_OFF_1:
  479. set_north_red();
  480. set_south_off();
  481. set_east_red();
  482. set_west_red();
  483. break;
  484.  
  485. case BLINKING_SOUTH_ON_2:
  486. set_north_red();
  487. set_south_green();
  488. set_east_red();
  489. set_west_red();
  490. break;
  491.  
  492. case BLINKING_SOUTH_OFF_2:
  493. set_north_red();
  494. set_south_off();
  495. set_east_red();
  496. set_west_red();
  497. break;
  498.  
  499. case BLINKING_SOUTH_ON_3:
  500. set_north_red();
  501. set_south_green();
  502. set_east_red();
  503. set_west_red();
  504. break;
  505.  
  506. case BLINKING_SOUTH_OFF_3:
  507. set_north_red();
  508. set_south_off();
  509. set_east_red();
  510. set_west_red();
  511. break;
  512.  
  513. case YELLOW_SOUTH:
  514. set_north_red();
  515. set_south_yellow();
  516. set_east_red();
  517. set_west_red();
  518. break;
  519.  
  520. case GREEN_EAST:
  521. set_north_red();
  522. set_south_red();
  523. set_east_green();
  524. set_west_red();
  525. break;
  526.  
  527. case BLINKING_EAST_ON_1:
  528. set_north_red();
  529. set_south_red();
  530. set_east_green();
  531. set_west_red();
  532. break;
  533.  
  534. case BLINKING_EAST_OFF_1:
  535. set_north_red();
  536. set_south_red();
  537. set_east_off();
  538. set_west_red();
  539. break;
  540.  
  541. case BLINKING_EAST_ON_2:
  542. set_north_red();
  543. set_south_red();
  544. set_east_green();
  545. set_west_red();
  546. break;
  547.  
  548. case BLINKING_EAST_OFF_2:
  549. set_north_red();
  550. set_south_red();
  551. set_east_off();
  552. set_west_red();
  553. break;
  554.  
  555. case BLINKING_EAST_ON_3:
  556. set_north_red();
  557. set_south_red();
  558. set_east_green();
  559. set_west_red();
  560. break;
  561.  
  562. case BLINKING_EAST_OFF_3:
  563. set_north_red();
  564. set_south_red();
  565. set_east_off();
  566. set_west_red();
  567. break;
  568.  
  569. case YELLOW_EAST:
  570. set_north_red();
  571. set_south_red();
  572. set_east_yellow();
  573. set_west_red();
  574. break;
  575.  
  576. case GREEN_WEST:
  577. set_north_red();
  578. set_south_red();
  579. set_east_red();
  580. set_west_green();
  581. break;
  582.  
  583. case BLINKING_WEST_ON_1:
  584. set_north_red();
  585. set_south_red();
  586. set_east_red();
  587. set_west_green();
  588. break;
  589.  
  590. case BLINKING_WEST_OFF_1:
  591. set_north_red();
  592. set_south_red();
  593. set_east_red();
  594. set_west_off();
  595. break;
  596.  
  597. case BLINKING_WEST_ON_2:
  598. set_north_red();
  599. set_south_red();
  600. set_east_red();
  601. set_west_green();
  602. break;
  603.  
  604. case BLINKING_WEST_OFF_2:
  605. set_north_red();
  606. set_south_red();
  607. set_east_red();
  608. set_west_off();
  609. break;
  610.  
  611. case BLINKING_WEST_ON_3:
  612. set_north_red();
  613. set_south_red();
  614. set_east_red();
  615. set_west_green();
  616. break;
  617.  
  618. case BLINKING_WEST_OFF_3:
  619. set_north_red();
  620. set_south_red();
  621. set_east_red();
  622. set_west_off();
  623. break;
  624.  
  625. case YELLOW_WEST:
  626. set_north_red();
  627. set_south_red();
  628. set_east_red();
  629. set_west_yellow();
  630. break;
  631.  
  632. default:
  633. break;
  634. }
  635. }
  636. return 0;
  637. }
  638.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty