ibm4704.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. Copyright 2014 Jun WAKO <wakojun@gmail.com>
  3. */
  4. #pragma once
  5. #define IBM4704_ERR_NONE 0
  6. #define IBM4704_ERR_PARITY 0x70
  7. void ibm4704_init(void);
  8. uint8_t ibm4704_send(uint8_t data);
  9. uint8_t ibm4704_recv_response(void);
  10. uint8_t ibm4704_recv(void);
  11. /* Check pin configuration */
  12. #if !(defined(IBM4704_CLOCK_PORT) && \
  13. defined(IBM4704_CLOCK_PIN) && \
  14. defined(IBM4704_CLOCK_DDR) && \
  15. defined(IBM4704_CLOCK_BIT))
  16. # error "ibm4704 clock pin configuration is required in config.h"
  17. #endif
  18. #if !(defined(IBM4704_DATA_PORT) && \
  19. defined(IBM4704_DATA_PIN) && \
  20. defined(IBM4704_DATA_DDR) && \
  21. defined(IBM4704_DATA_BIT))
  22. # error "ibm4704 data pin configuration is required in config.h"
  23. #endif
  24. /*--------------------------------------------------------------------
  25. * static functions
  26. *------------------------------------------------------------------*/
  27. static inline void clock_lo(void)
  28. {
  29. IBM4704_CLOCK_PORT &= ~(1<<IBM4704_CLOCK_BIT);
  30. IBM4704_CLOCK_DDR |= (1<<IBM4704_CLOCK_BIT);
  31. }
  32. static inline void clock_hi(void)
  33. {
  34. /* input with pull up */
  35. IBM4704_CLOCK_DDR &= ~(1<<IBM4704_CLOCK_BIT);
  36. IBM4704_CLOCK_PORT |= (1<<IBM4704_CLOCK_BIT);
  37. }
  38. static inline bool clock_in(void)
  39. {
  40. IBM4704_CLOCK_DDR &= ~(1<<IBM4704_CLOCK_BIT);
  41. IBM4704_CLOCK_PORT |= (1<<IBM4704_CLOCK_BIT);
  42. _delay_us(1);
  43. return IBM4704_CLOCK_PIN&(1<<IBM4704_CLOCK_BIT);
  44. }
  45. static inline void data_lo(void)
  46. {
  47. IBM4704_DATA_PORT &= ~(1<<IBM4704_DATA_BIT);
  48. IBM4704_DATA_DDR |= (1<<IBM4704_DATA_BIT);
  49. }
  50. static inline void data_hi(void)
  51. {
  52. /* input with pull up */
  53. IBM4704_DATA_DDR &= ~(1<<IBM4704_DATA_BIT);
  54. IBM4704_DATA_PORT |= (1<<IBM4704_DATA_BIT);
  55. }
  56. static inline bool data_in(void)
  57. {
  58. IBM4704_DATA_DDR &= ~(1<<IBM4704_DATA_BIT);
  59. IBM4704_DATA_PORT |= (1<<IBM4704_DATA_BIT);
  60. _delay_us(1);
  61. return IBM4704_DATA_PIN&(1<<IBM4704_DATA_BIT);
  62. }
  63. static inline uint16_t wait_clock_lo(uint16_t us)
  64. {
  65. while (clock_in() && us) { asm(""); _delay_us(1); us--; }
  66. return us;
  67. }
  68. static inline uint16_t wait_clock_hi(uint16_t us)
  69. {
  70. while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
  71. return us;
  72. }
  73. static inline uint16_t wait_data_lo(uint16_t us)
  74. {
  75. while (data_in() && us) { asm(""); _delay_us(1); us--; }
  76. return us;
  77. }
  78. static inline uint16_t wait_data_hi(uint16_t us)
  79. {
  80. while (!data_in() && us) { asm(""); _delay_us(1); us--; }
  81. return us;
  82. }
  83. /* idle state that device can send */
  84. static inline void idle(void)
  85. {
  86. clock_hi();
  87. data_hi();
  88. }
  89. /* inhibit device to send
  90. * keyboard checks Data line on start bit(Data:hi) and it stops sending if Data line is low.
  91. */
  92. static inline void inhibit(void)
  93. {
  94. clock_hi();
  95. data_lo();
  96. }