ibm4704.h 2.8 KB

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