expander.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. void expander_init(unsigned char addr, unsigned char p1in, unsigned char p2in){
  14. addr += EXPANDER_ADDR;
  15. expander_write_all();
  16. expander_set_dir(addr, p1in, p2in);
  17. }
  18. void expander_set_dir(unsigned char addr, unsigned char p1in, unsigned char p2in){
  19. System.global_error |= I2C_SendCommand3byte(addr, CMD_PORT0_CONFIG, p1in, p2in);
  20. }
  21. unsigned int expander_read(unsigned char addr){
  22. unsigned char low, high;
  23. System.global_error |= I2C_ReceiveCommand(addr, CMD_PORT0_INPUT, &low);
  24. System.global_error |= I2C_ReceiveCommand(addr, CMD_PORT1_INPUT, &high);
  25. return (unsigned int)low | (((unsigned int) high)<<8);
  26. }
  27. unsigned int expander_read_byte(unsigned char addr, unsigned char reg){
  28. unsigned char result;
  29. System.global_error |= I2C_ReceiveCommand(addr, reg?CMD_PORT1_INPUT:CMD_PORT0_INPUT, &result);
  30. return result;
  31. }
  32. void expander_write(unsigned char expaddr){
  33. unsigned char addr = EXPANDER_ADDR + expaddr;
  34. System.global_error |= I2C_SendCommand3byte(addr, CMD_PORT0_OUTPUT, exp_output[expaddr*2], exp_output[expaddr*2 + 1]);
  35. }
  36. void expander_write_all(void){
  37. unsigned char i;
  38. for(i=0; i<EXPANDER_COUNT; i++)
  39. expander_write(i);
  40. }
  41. void expander_set_bit(unsigned char port, unsigned char val, unsigned char on){
  42. if(on){
  43. exp_output[port] |= val;
  44. } else {
  45. exp_output[port] &= ~val;
  46. }
  47. /* if(SREG & _BV(SREG_I)){
  48. System.expander_pending = 1;
  49. } else {*/
  50. expander_write(port / 2);
  51. // }
  52. }
  53. void expander_set_bit_no_send(unsigned char port, unsigned char val, unsigned char on){
  54. if(on){
  55. exp_output[port] |= val;
  56. } else {
  57. exp_output[port] &= ~val;
  58. }
  59. }