ethspi.c

Go to the documentation of this file.
00001 /**************************************************************************/
00017 #include "ethspi.h"
00018 #include "em_device.h"
00019 #include "em_usart.h"
00020 #include "em_gpio.h"
00021 #include "em_cmu.h"
00022 #include <stdio.h>
00023 
00025 static void ETHSPI_SetChipSelect(bool value);
00026 static uint8_t ETHSPI_XferSpi(uint8_t data);
00027 
00029 static const uint8_t bitEnable[] = { 0x00, 0x1, 0x3, 0x7, 0xf };
00030 
00032 static const USART_InitSync_TypeDef initSpi =
00033 { usartEnable,    /* Enable RX/TX when init completed. */
00034   48000000,       /* Use 48MHz reference clock */
00035   7000000,        /* 7 Mbits/s. */
00036   usartDatabits8, /* 8 databits. */
00037   true,           /* Master mode. */
00038   true,           /* Send most significant bit first. */
00039   usartClockMode0,
00040 #if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY) || defined(_EFM32_WONDER_FAMILY)
00041   false,
00042   usartPrsRxCh0,
00043   false,
00044 #endif
00045 };
00048 /**************************************************************************/
00055 void ETHSPI_Init(void)
00056 {
00057   USART_TypeDef *spi;
00058 
00059   /* Enabling clock to USART */
00060   CMU_ClockEnable(cmuClock_HFPER, true);
00061   CMU_ClockEnable(ETH_USART_CLK, true);
00062   CMU_ClockEnable(cmuClock_GPIO, true);
00063 
00064   /* Setup SPI at USART0 */
00065   spi = ETH_USART_USED;
00066   /* Configure SPI */
00067   USART_Reset(spi);
00068   /* Initialize USART1, in SPI master mode. */
00069   USART_InitSync(spi, &initSpi);
00070   /* Enabling pins and setting location, SPI CS not enable */
00071   spi->ROUTE = USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_CLKPEN | USART_ROUTE_LOCATION_LOC1;
00072   /* Enabling TX and RX */
00073   spi->CMD = USART_CMD_TXEN | USART_CMD_RXEN;
00074   /* Clear previous interrupts */
00075   spi->IFC = _USART_IFC_MASK;
00076 
00077   /* IO configuration (USART 1, Location #1) */
00078   GPIO_PinModeSet(SPI_MOSI_PORT, SPI_MOSI_PIN, gpioModePushPull, 1);
00079   GPIO_PinModeSet(SPI_MISO_PORT, SPI_MISO_PIN, gpioModeInput, 0);
00080   GPIO_PinModeSet(SPI_CLK_PORT, SPI_CLK_PIN, gpioModePushPull, 0);
00081   GPIO_PinModeSet(SPI_CS_PORT, SPI_CS_PIN, gpioModePushPull, 1);
00082 }
00083 
00084 /**************************************************************************/
00091 static uint8_t ETHSPI_XferSpi(uint8_t data)
00092 {
00093   USART_TypeDef *spi = USART1;
00094 
00095   spi->TXDATA = data;
00096   while (!(spi->STATUS & USART_STATUS_TXC))
00097   {
00098   }
00099   return (uint8_t)(spi->RXDATA);
00100 }
00101 
00102 
00103 /**************************************************************************/
00108 static void ETHSPI_SetChipSelect(bool value)
00109 {
00110   if (value)
00111   {
00112     /* Enable chip select */
00113     GPIO_PinOutClear(SPI_CS_PORT, SPI_CS_PIN);
00114   }
00115   else
00116   {
00117     /* Disable chip select */
00118     GPIO_PinOutSet(SPI_CS_PORT, SPI_CS_PIN);
00119   }
00120 }
00121 
00122 
00123 /**************************************************************************/
00129 void ETHSPI_ReadRegister(uint8_t reg, int numBytes, void *data)
00130 {
00131   uint8_t first, second;
00132   uint8_t *rxBuffer = (uint8_t *) data;
00133 
00134   EFM_ASSERT(reg > 0 && reg < 0xFF);
00135   EFM_ASSERT(numBytes > 0 && numBytes < 5);
00136   EFM_ASSERT(data != NULL);
00137 
00138   /* First Opcode:00, ByteEnable and MSB of register address */
00139   first  = bitEnable[numBytes] << (SHIFT_VAL + (reg & REG_MASK));
00140   first |= ((reg & ADDRESS_MS2B_MASK) >> ADDRESS_MS2B_POS);
00141 
00142   /* Second LSB of register address, last 4 LSB is ignored */
00143   second = (reg << SHIFT_VAL);
00144 
00145   /* Enable chip select */
00146   ETHSPI_SetChipSelect(true);
00147 
00148   ETHSPI_XferSpi(first);
00149   ETHSPI_XferSpi(second);
00150 
00151   /* Read data back */
00152   while (numBytes--)
00153   {
00154     *rxBuffer++ = ETHSPI_XferSpi(BOGUS_BYTE);
00155   }
00156   /* Disable chip select */
00157   ETHSPI_SetChipSelect(false);
00158 }
00159 
00160 
00161 /**************************************************************************/
00167 void ETHSPI_WriteRegister(uint8_t reg, int numBytes, void *data)
00168 {
00169   uint8_t first, second;
00170   uint8_t *txBuffer = (uint8_t *) data;
00171 
00172   EFM_ASSERT(reg > 0 && reg < 0xFF);
00173   EFM_ASSERT(numBytes > 0 && numBytes < 5);
00174   EFM_ASSERT(data != NULL);
00175 
00176   /* First Opcode:01, ByteEnable and MSB of register address */
00177   first  = OPCODE_REG_WRITE | (bitEnable[numBytes] << (SHIFT_VAL + (reg & REG_MASK)));
00178   first |= ((reg & ADDRESS_MS2B_MASK) >> ADDRESS_MS2B_POS);
00179   /* Second LSB of register address, last 4 LSB is ignored */
00180   second = (reg << SHIFT_VAL);
00181 
00182   /* Enable chip select */
00183   ETHSPI_SetChipSelect(true);
00184   ETHSPI_XferSpi(first);
00185   ETHSPI_XferSpi(second);
00186 
00187   /* Write Packet data */
00188   while (numBytes--)
00189   {
00190     ETHSPI_XferSpi(*txBuffer++);
00191   }
00192   /* Disable chip select */
00193   ETHSPI_SetChipSelect(false);
00194 }
00195 
00196 
00197 /**************************************************************************/
00200 void ETHSPI_StartReadFIFO(void)
00201 {
00202   /* Enable chip select */
00203   ETHSPI_SetChipSelect(true);
00204   /* Send Read command */
00205   ETHSPI_XferSpi(OPCODE_FIFO_READ);
00206 }
00207 
00208 
00209 /*************************************************************************/
00212 void ETHSPI_StartWriteFIFO(void)
00213 {
00214   /* Enable chip select */
00215   ETHSPI_SetChipSelect(true);
00216   /* Send Write command */
00217   ETHSPI_XferSpi(OPCODE_FIFO_WRITE);
00218 }
00219 
00220 
00221 /*************************************************************************/
00224 void ETHSPI_StopFIFO(void)
00225 {
00226   /* Disable chip select */
00227   ETHSPI_SetChipSelect(false);
00228 }
00229 
00230 
00231 /*************************************************************************/
00236 void ETHSPI_ReadFifoContinue(int numBytes, uint8_t *data)
00237 {
00238   EFM_ASSERT(numBytes >= 0 && numBytes < 12000);
00239   EFM_ASSERT(data != NULL);
00240 
00241   uint8_t *rxBuffer = (uint8_t *) data;
00242   while (numBytes--)
00243   {
00244     *rxBuffer++ = ETHSPI_XferSpi(BOGUS_BYTE);
00245   }
00246 }
00247 
00248 
00249 /*************************************************************************/
00254 void ETHSPI_WriteFifoContinue(int numBytes, uint8_t *data)
00255 {
00256 
00257   EFM_ASSERT(numBytes >= 0 && numBytes < 12000);
00258   EFM_ASSERT(data != NULL);
00259 
00260   uint8_t *txBuffer = (uint8_t *) data;
00261   while (numBytes--)
00262   {
00263     ETHSPI_XferSpi(*txBuffer++);
00264   }
00265 }