ethspi.c

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