avr_isp_spi_sw.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #include "avr_isp_spi_sw.h"
  2. #include <furi.h>
  3. #define AVR_ISP_SPI_SW_MISO &gpio_ext_pa6
  4. #define AVR_ISP_SPI_SW_MOSI &gpio_ext_pa7
  5. #define AVR_ISP_SPI_SW_SCK &gpio_ext_pb3
  6. #define AVR_ISP_RESET &gpio_ext_pb2
  7. struct AvrIspSpiSw {
  8. AvrIspSpiSwSpeed speed_wait_time;
  9. const GpioPin* miso;
  10. const GpioPin* mosi;
  11. const GpioPin* sck;
  12. const GpioPin* res;
  13. };
  14. AvrIspSpiSw* avr_isp_spi_sw_init(AvrIspSpiSwSpeed speed) {
  15. AvrIspSpiSw* instance = malloc(sizeof(AvrIspSpiSw));
  16. instance->speed_wait_time = speed;
  17. instance->miso = AVR_ISP_SPI_SW_MISO;
  18. instance->mosi = AVR_ISP_SPI_SW_MOSI;
  19. instance->sck = AVR_ISP_SPI_SW_SCK;
  20. instance->res = AVR_ISP_RESET;
  21. furi_hal_gpio_init(instance->miso, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
  22. furi_hal_gpio_write(instance->mosi, false);
  23. furi_hal_gpio_init(instance->mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
  24. furi_hal_gpio_write(instance->sck, false);
  25. furi_hal_gpio_init(instance->sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
  26. furi_hal_gpio_init(instance->res, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
  27. return instance;
  28. }
  29. void avr_isp_spi_sw_free(AvrIspSpiSw* instance) {
  30. furi_assert(instance);
  31. furi_hal_gpio_init(instance->res, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
  32. furi_hal_gpio_init(instance->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
  33. furi_hal_gpio_init(instance->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
  34. furi_hal_gpio_init(instance->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
  35. free(instance);
  36. }
  37. uint8_t avr_isp_spi_sw_txrx(AvrIspSpiSw* instance, uint8_t data) {
  38. furi_assert(instance);
  39. for(uint8_t i = 0; i < 8; ++i) {
  40. furi_hal_gpio_write(instance->mosi, (data & 0x80) ? true : false);
  41. furi_hal_gpio_write(instance->sck, true);
  42. if(instance->speed_wait_time != AvrIspSpiSwSpeed1Mhz)
  43. furi_delay_us(instance->speed_wait_time - 1);
  44. data = (data << 1) | furi_hal_gpio_read(instance->miso); //-V792
  45. furi_hal_gpio_write(instance->sck, false);
  46. if(instance->speed_wait_time != AvrIspSpiSwSpeed1Mhz)
  47. furi_delay_us(instance->speed_wait_time - 1);
  48. }
  49. return data;
  50. }
  51. void avr_isp_spi_sw_res_set(AvrIspSpiSw* instance, bool state) {
  52. furi_assert(instance);
  53. furi_hal_gpio_write(instance->res, state);
  54. }
  55. void avr_isp_spi_sw_sck_set(AvrIspSpiSw* instance, bool state) {
  56. furi_assert(instance);
  57. furi_hal_gpio_write(instance->sck, state);
  58. }