ksz8851snl_spi.c
Go to the documentation of this file.00001
00015 #include <stdio.h>
00016 #include <stdint.h>
00017
00018 #include "ksz8851snl_spi.h"
00019 #include "em_assert.h"
00020 #include "em_common.h"
00021 #include "em_gpio.h"
00022 #include "spidrv.h"
00023
00024 #define BOGUS_BYTE 0xFF
00025 #define REG_MASK 0x03
00026 #define OPCODE_REG_READ 0x00
00027 #define OPCODE_REG_WRITE 0x40
00028 #define OPCODE_FIFO_READ 0x80
00029 #define OPCODE_FIFO_WRITE 0xC0
00030 #define ADDRESS_MS2B_POS 0x06
00031 #define ADDRESS_SHIFT 0x02
00032 #define BYTE_ENABLE 0x03
00033 #define BYTE_ENABLE_SHIFT 0x02
00035
00036
00037 #define ETH_CS_PIN 3
00038 #define ETH_CS_PORT gpioPortD
00042 static SPIDRV_HandleData_t spiHandleData;
00043 static SPIDRV_Handle_t spiHandle = &spiHandleData;
00044
00048
00057 void KSZ8851SNL_SPI_Init(void)
00058 {
00059 Ecode_t result;
00060 SPIDRV_Init_t initData = SPIDRV_MASTER_USART1;
00061 initData.bitRate = 8000000;
00062 initData.frameLength = 8;
00063 initData.dummyTxValue = BOGUS_BYTE;
00064 initData.bitOrder = spidrvBitOrderMsbFirst;
00065 initData.clockMode = spidrvClockMode0;
00066 initData.csControl = spidrvCsControlApplication;
00067
00068 result = SPIDRV_Init(spiHandle, &initData);
00069 EFM_ASSERT(result == ECODE_EMDRV_SPIDRV_OK);
00070
00071 GPIO_PinModeSet(ETH_CS_PORT, ETH_CS_PIN, gpioModePushPull, 1);
00072 }
00073
00074
00075
00085 static void KSZ8851SNL_SPI_Transmit(int numBytes, const uint8_t * data)
00086 {
00087 Ecode_t result;
00088 int remaining = numBytes;
00089
00090
00091
00092
00093
00094 do {
00095 int count = EFM32_MIN(remaining, DMADRV_MAX_XFER_COUNT);
00096 result = SPIDRV_MTransmitB(spiHandle, data, count);
00097 remaining -= count;
00098 data += count;
00099 } while (result == ECODE_EMDRV_SPIDRV_OK && remaining > 0);
00100
00101 EFM_ASSERT(result == ECODE_EMDRV_SPIDRV_OK);
00102 }
00103
00104
00105
00115 static void KSZ8851SNL_SPI_Receive(int numBytes, uint8_t * buffer)
00116 {
00117 Ecode_t result;
00118 int remaining = numBytes;
00119
00120
00121
00122
00123
00124 do {
00125 int count = EFM32_MIN(remaining, DMADRV_MAX_XFER_COUNT);
00126 result = SPIDRV_MReceiveB(spiHandle, buffer, count);
00127 remaining -= count;
00128 buffer += count;
00129 } while (result == ECODE_EMDRV_SPIDRV_OK && remaining > 0);
00130
00131 EFM_ASSERT(result == ECODE_EMDRV_SPIDRV_OK);
00132 }
00133
00134
00135
00144 static void KSZ8851SNL_SPI_SetChipSelect(bool enable)
00145 {
00146 if (enable)
00147 {
00148 GPIO_PinOutClear(ETH_CS_PORT, ETH_CS_PIN);
00149 }
00150 else
00151 {
00152 GPIO_PinOutSet(ETH_CS_PORT, ETH_CS_PIN);
00153 }
00154 }
00155
00156
00157
00167 uint16_t KSZ8851SNL_SPI_ReadRegister(uint8_t reg)
00168 {
00169 uint16_t value = 0x0000;
00170 uint8_t txBuffer[4];
00171 uint8_t rxBuffer[4];
00172
00185 txBuffer[0] = OPCODE_REG_READ;
00186 txBuffer[0] |= BYTE_ENABLE << (BYTE_ENABLE_SHIFT + (reg & REG_MASK));
00187 txBuffer[0] |= (reg >> ADDRESS_MS2B_POS);
00188 txBuffer[1] = (reg << ADDRESS_SHIFT) & 0xf0;
00189
00190 KSZ8851SNL_SPI_SetChipSelect(true);
00191 SPIDRV_MTransferB(spiHandle, txBuffer, rxBuffer, 4);
00192 KSZ8851SNL_SPI_SetChipSelect(false);
00193
00194 value = (rxBuffer[3] << 8) | rxBuffer[2];
00195 return value;
00196 }
00197
00198
00199
00209 void KSZ8851SNL_SPI_WriteRegister(uint8_t reg, uint16_t value)
00210 {
00211 uint8_t txBuffer[4];
00212
00225 txBuffer[0] = OPCODE_REG_WRITE | (BYTE_ENABLE << (BYTE_ENABLE_SHIFT + (reg & REG_MASK)));
00226 txBuffer[0] |= reg >> ADDRESS_MS2B_POS;
00227 txBuffer[1] = (reg << ADDRESS_SHIFT) & 0xf0;
00228 txBuffer[2] = value & 0xff;
00229 txBuffer[3] = (value >> 8) & 0xff;
00230
00231 KSZ8851SNL_SPI_SetChipSelect(true);
00232 KSZ8851SNL_SPI_Transmit(4, txBuffer);
00233 KSZ8851SNL_SPI_SetChipSelect(false);
00234 }
00235
00236
00237
00257 void KSZ8851SNL_SPI_ReadFifo(int numBytes, uint8_t *data)
00258 {
00259 EFM_ASSERT(numBytes >= 0 && numBytes < 12000);
00260 EFM_ASSERT(data != NULL);
00261
00262 uint8_t cmd = OPCODE_FIFO_READ;
00263 uint8_t dummy[4];
00264
00265 KSZ8851SNL_SPI_SetChipSelect(true);
00266 KSZ8851SNL_SPI_Transmit(1, &cmd);
00267 KSZ8851SNL_SPI_Receive(4, dummy);
00268 KSZ8851SNL_SPI_Receive(numBytes, data);
00269 KSZ8851SNL_SPI_SetChipSelect(false);
00270 }
00271
00272
00275 void KSZ8851SNL_SPI_WriteFifoBegin(void)
00276 {
00277 uint8_t cmd = OPCODE_FIFO_WRITE;
00278
00279 KSZ8851SNL_SPI_SetChipSelect(true);
00280
00281 KSZ8851SNL_SPI_Transmit(1, &cmd);
00282 }
00283
00284
00289 void KSZ8851SNL_SPI_WriteFifo(int numBytes, const uint8_t *data)
00290 {
00291 EFM_ASSERT(numBytes >= 0 && numBytes < 12000);
00292 EFM_ASSERT(data != NULL);
00293
00294 KSZ8851SNL_SPI_Transmit(numBytes, data);
00295 }
00296
00297
00298
00301 void KSZ8851SNL_SPI_WriteFifoEnd(void)
00302 {
00303 KSZ8851SNL_SPI_SetChipSelect(false);
00304 }