/** * \file * * * \brief Emulated SPI Master for DSP firmware download (impl.) * * * \author Francesco Sacchi * \author Daniele Basile */ #include "spi_bitbang.h" #include "hw/hw_spi.h" #include "cfg/cfg_spi_bitbang.h" #include #include void spi_assertSS(void) { ATOMIC(SS_ACTIVE()); } void spi_deassertSS(void) { ATOMIC(SS_INACTIVE()); } /** * Send byte \c c over MOSI line, CONFIG_SPI_DATAORDER first. * SS pin state is left unchanged. */ uint8_t spi_sendRecv(uint8_t c) { uint8_t data = 0; uint8_t shift = SPI_DATAORDER_START; ATOMIC( for (int i = 0; i < 8; i++) { /* Shift the i-th bit to MOSI */ if (c & shift) MOSI_HIGH(); else MOSI_LOW(); /* Assert clock */ SCK_ACTIVE(); data |= IS_MISO_HIGH() ? shift : 0; /* De-assert clock */ SCK_INACTIVE(); SPI_DATAORDER_SHIFT(shift); } ); return data; } MOD_DEFINE(spi); void spi_init(void) { ATOMIC(SPI_HW_INIT()); MOD_INIT(spi); } /** * Read \param len from spi, and put it in \param _buff . */ void spi_read(void *_buff, size_t len) { uint8_t *buff = (uint8_t *)_buff; while (len--) /* Read byte from spi and put it in buffer. */ *buff++ = spi_sendRecv(0); } /** * Write \param len to spi, and take it from \param _buff . */ void spi_write(const void *_buff, size_t len) { const uint8_t *buff = (const uint8_t *)_buff; while (len--) /* Write byte pointed at by *buff to spi */ spi_sendRecv(*buff++); }