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,
00052 48000000,
00053 7000000,
00054 usartDatabits8,
00055 true,
00056 true,
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
00078 CMU_ClockEnable(cmuClock_HFPER, true);
00079 CMU_ClockEnable(ETH_USART_CLK, true);
00080 CMU_ClockEnable(cmuClock_GPIO, true);
00081
00082
00083 spi = ETH_USART_USED;
00084
00085 USART_Reset(spi);
00086
00087 USART_InitSync(spi, &initSpi);
00088
00089 spi->ROUTE = USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_CLKPEN | USART_ROUTE_LOCATION_LOC1;
00090
00091 spi->CMD = USART_CMD_TXEN | USART_CMD_RXEN;
00092
00093 spi->IFC = _USART_IFC_MASK;
00094
00095
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
00131 GPIO_PinOutClear(SPI_CS_PORT, SPI_CS_PIN);
00132 }
00133 else
00134 {
00135
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
00157 first = bitEnable[numBytes] << (SHIFT_VAL + (reg & REG_MASK));
00158 first |= ((reg & ADDRESS_MS2B_MASK) >> ADDRESS_MS2B_POS);
00159
00160
00161 second = (reg << SHIFT_VAL);
00162
00163
00164 ETHSPI_SetChipSelect(true);
00165
00166 ETHSPI_XferSpi(first);
00167 ETHSPI_XferSpi(second);
00168
00169
00170 while (numBytes--)
00171 {
00172 *rxBuffer++ = ETHSPI_XferSpi(BOGUS_BYTE);
00173 }
00174
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
00195 first = OPCODE_REG_WRITE | (bitEnable[numBytes] << (SHIFT_VAL + (reg & REG_MASK)));
00196 first |= ((reg & ADDRESS_MS2B_MASK) >> ADDRESS_MS2B_POS);
00197
00198 second = (reg << SHIFT_VAL);
00199
00200
00201 ETHSPI_SetChipSelect(true);
00202 ETHSPI_XferSpi(first);
00203 ETHSPI_XferSpi(second);
00204
00205
00206 while (numBytes--)
00207 {
00208 ETHSPI_XferSpi(*txBuffer++);
00209 }
00210
00211 ETHSPI_SetChipSelect(false);
00212 }
00213
00214
00215
00218 void ETHSPI_StartReadFIFO(void)
00219 {
00220
00221 ETHSPI_SetChipSelect(true);
00222
00223 ETHSPI_XferSpi(OPCODE_FIFO_READ);
00224 }
00225
00226
00227
00230 void ETHSPI_StartWriteFIFO(void)
00231 {
00232
00233 ETHSPI_SetChipSelect(true);
00234
00235 ETHSPI_XferSpi(OPCODE_FIFO_WRITE);
00236 }
00237
00238
00239
00242 void ETHSPI_StopFIFO(void)
00243 {
00244
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 }