ibm4704.h 2.8 KB

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