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,
00034 48000000,
00035 7000000,
00036 usartDatabits8,
00037 true,
00038 true,
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
00060 CMU_ClockEnable(cmuClock_HFPER, true);
00061 CMU_ClockEnable(ETH_USART_CLK, true);
00062 CMU_ClockEnable(cmuClock_GPIO, true);
00063
00064
00065 spi = ETH_USART_USED;
00066
00067 USART_Reset(spi);
00068
00069 USART_InitSync(spi, &initSpi);
00070
00071 spi->ROUTE = USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_CLKPEN | USART_ROUTE_LOCATION_LOC1;
00072
00073 spi->CMD = USART_CMD_TXEN | USART_CMD_RXEN;
00074
00075 spi->IFC = _USART_IFC_MASK;
00076
00077
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
00113 GPIO_PinOutClear(SPI_CS_PORT, SPI_CS_PIN);
00114 }
00115 else
00116 {
00117
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
00139 first = bitEnable[numBytes] << (SHIFT_VAL + (reg & REG_MASK));
00140 first |= ((reg & ADDRESS_MS2B_MASK) >> ADDRESS_MS2B_POS);
00141
00142
00143 second = (reg << SHIFT_VAL);
00144
00145
00146 ETHSPI_SetChipSelect(true);
00147
00148 ETHSPI_XferSpi(first);
00149 ETHSPI_XferSpi(second);
00150
00151
00152 while (numBytes--)
00153 {
00154 *rxBuffer++ = ETHSPI_XferSpi(BOGUS_BYTE);
00155 }
00156
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
00177 first = OPCODE_REG_WRITE | (bitEnable[numBytes] << (SHIFT_VAL + (reg & REG_MASK)));
00178 first |= ((reg & ADDRESS_MS2B_MASK) >> ADDRESS_MS2B_POS);
00179
00180 second = (reg << SHIFT_VAL);
00181
00182
00183 ETHSPI_SetChipSelect(true);
00184 ETHSPI_XferSpi(first);
00185 ETHSPI_XferSpi(second);
00186
00187
00188 while (numBytes--)
00189 {
00190 ETHSPI_XferSpi(*txBuffer++);
00191 }
00192
00193 ETHSPI_SetChipSelect(false);
00194 }
00195
00196
00197
00200 void ETHSPI_StartReadFIFO(void)
00201 {
00202
00203 ETHSPI_SetChipSelect(true);
00204
00205 ETHSPI_XferSpi(OPCODE_FIFO_READ);
00206 }
00207
00208
00209
00212 void ETHSPI_StartWriteFIFO(void)
00213 {
00214
00215 ETHSPI_SetChipSelect(true);
00216
00217 ETHSPI_XferSpi(OPCODE_FIFO_WRITE);
00218 }
00219
00220
00221
00224 void ETHSPI_StopFIFO(void)
00225 {
00226
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 }