dbg_slave.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /*
  2. * PiLC HAT firmware
  3. * I2C debugging slave
  4. *
  5. * Copyright (c) 2016 Michael Buesch <m@bues.ch>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. */
  21. #include "dbg_slave.h"
  22. #include "i2c_slave.h"
  23. #include "util.h"
  24. #define DBGSLAVE_MAX_DELAY 42
  25. static uint8_t dbgslave_data;
  26. static uint8_t dbgslave_tx_delay;
  27. static uint8_t dbgslave_rx_delay;
  28. static void dbgslave_delay(uint8_t delay)
  29. {
  30. while (delay--)
  31. __asm__ __volatile__ ("nop\n");
  32. }
  33. static uint8_t dbgslave_transmit(bool start)
  34. {
  35. dbgslave_delay(dbgslave_tx_delay);
  36. if (++dbgslave_tx_delay >= DBGSLAVE_MAX_DELAY)
  37. dbgslave_tx_delay = 0;
  38. return (uint8_t)(dbgslave_data | (start ? 0x02 : 0x00));
  39. }
  40. static void dbgslave_receive(bool start, uint8_t data)
  41. {
  42. dbgslave_delay(dbgslave_rx_delay);
  43. if (++dbgslave_rx_delay >= DBGSLAVE_MAX_DELAY)
  44. dbgslave_rx_delay = 0;
  45. dbgslave_data = (uint8_t)((data & ~0x03) | (start ? 0x01 : 0x00));
  46. }
  47. static const struct i2c_slave_ops __flash dbgslave_i2c_slave_ops = {
  48. .transmit = dbgslave_transmit,
  49. .receive = dbgslave_receive,
  50. };
  51. void dbgslave_init(void)
  52. {
  53. i2cs_add_slave(DBGSLAVE_ADDR, &dbgslave_i2c_slave_ops);
  54. }