expander.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*
  2. * expander.c
  3. * k4be 2022
  4. * License: BSD
  5. *
  6. * PCA9539/TCA9539 GPIO expander driver
  7. */
  8. #include "main.h"
  9. #include "I2C.h"
  10. #include "expander.h"
  11. #include <avr/io.h>
  12. unsigned char exp_output[EXPANDER_COUNT*2];
  13. unsigned char directions[EXPANDER_COUNT*2];
  14. void expander_init(unsigned char addr, unsigned char p1in, unsigned char p2in){
  15. addr += EXPANDER_ADDR;
  16. expander_write_all();
  17. System.global_error |= I2C_SendCommand3byte(addr, CMD_PORT0_CONFIG, p1in, p2in);
  18. }
  19. void expander_set_dir(unsigned char addr, unsigned char p1in, unsigned char p2in){
  20. if(p1in == directions[addr*2] && p2in == directions[addr*2 + 1])
  21. return; /* no change needed, save one transaction */
  22. System.global_error |= I2C_SendCommand3byte(addr, CMD_PORT0_CONFIG, p1in, p2in);
  23. directions[addr*2] = p1in;
  24. directions[addr*2 + 1] = p2in;
  25. }
  26. unsigned int expander_read(unsigned char addr){
  27. unsigned char low, high;
  28. System.global_error |= I2C_ReceiveCommand(addr, CMD_PORT0_INPUT, &low);
  29. System.global_error |= I2C_ReceiveCommand(addr, CMD_PORT1_INPUT, &high);
  30. return (unsigned int)low | (((unsigned int) high)<<8);
  31. }
  32. unsigned int expander_read_byte(unsigned char addr, unsigned char reg){
  33. unsigned char result;
  34. System.global_error |= I2C_ReceiveCommand(addr, reg?CMD_PORT1_INPUT:CMD_PORT0_INPUT, &result);
  35. return result;
  36. }
  37. void expander_write(unsigned char expaddr){
  38. unsigned char addr = EXPANDER_ADDR + expaddr;
  39. System.global_error |= I2C_SendCommand3byte(addr, CMD_PORT0_OUTPUT, exp_output[expaddr*2], exp_output[expaddr*2 + 1]);
  40. }
  41. void expander_write_all(void){
  42. unsigned char i;
  43. for(i=0; i<EXPANDER_COUNT; i++)
  44. expander_write(i);
  45. }
  46. void expander_set_bit(unsigned char port, unsigned char val, unsigned char on){
  47. if(on){
  48. exp_output[port] |= val;
  49. } else {
  50. exp_output[port] &= ~val;
  51. }
  52. /* if(SREG & _BV(SREG_I)){
  53. System.expander_pending = 1;
  54. } else {*/
  55. expander_write(port / 2);
  56. // }
  57. }
  58. void expander_set_bit_no_send(unsigned char port, unsigned char val, unsigned char on){
  59. if(on){
  60. exp_output[port] |= val;
  61. } else {
  62. exp_output[port] &= ~val;
  63. }
  64. }