raspiezo / mbed-dev

Dependents:   Nucleo_L432KC_Quadrature_Decoder_with_ADC_and_DAC

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Wed Mar 02 14:30:11 2016 +0000
Revision:
80:bdf1132a57cf
Parent:
0:9b334a45a8ff
Child:
144:ef7eb2e8f9f7
Synchronized with git revision de3b14ec9234d586b155fd24badc22775489a3dc

Full URL: https://github.com/mbedmicro/mbed/commit/de3b14ec9234d586b155fd24badc22775489a3dc/

latest changes to add arduino support, plus fixes for IOTSS BEID

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 0:9b334a45a8ff 1 /* MPS2 Peripheral Library
bogdanm 0:9b334a45a8ff 2 *
bogdanm 0:9b334a45a8ff 3 * Copyright (c) 2006-2015 ARM Limited
bogdanm 0:9b334a45a8ff 4 * All rights reserved.
bogdanm 0:9b334a45a8ff 5 *
bogdanm 0:9b334a45a8ff 6 * Redistribution and use in source and binary forms, with or without
bogdanm 0:9b334a45a8ff 7 * modification, are permitted provided that the following conditions are met:
bogdanm 0:9b334a45a8ff 8 *
bogdanm 0:9b334a45a8ff 9 * 1. Redistributions of source code must retain the above copyright notice,
bogdanm 0:9b334a45a8ff 10 * this list of conditions and the following disclaimer.
bogdanm 0:9b334a45a8ff 11 *
bogdanm 0:9b334a45a8ff 12 * 2. Redistributions in binary form must reproduce the above copyright notice,
bogdanm 0:9b334a45a8ff 13 * this list of conditions and the following disclaimer in the documentation
bogdanm 0:9b334a45a8ff 14 * and/or other materials provided with the distribution.
bogdanm 0:9b334a45a8ff 15 *
bogdanm 0:9b334a45a8ff 16 * 3. Neither the name of the copyright holder nor the names of its contributors
bogdanm 0:9b334a45a8ff 17 * may be used to endorse or promote products derived from this software without
bogdanm 0:9b334a45a8ff 18 * specific prior written permission.
bogdanm 0:9b334a45a8ff 19 *
bogdanm 0:9b334a45a8ff 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
bogdanm 0:9b334a45a8ff 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
bogdanm 0:9b334a45a8ff 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
bogdanm 0:9b334a45a8ff 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
bogdanm 0:9b334a45a8ff 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
bogdanm 0:9b334a45a8ff 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
bogdanm 0:9b334a45a8ff 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
bogdanm 0:9b334a45a8ff 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
bogdanm 0:9b334a45a8ff 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
bogdanm 0:9b334a45a8ff 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
bogdanm 0:9b334a45a8ff 30 * POSSIBILITY OF SUCH DAMAGE.
bogdanm 0:9b334a45a8ff 31 */
bogdanm 0:9b334a45a8ff 32
bogdanm 0:9b334a45a8ff 33 /*
bogdanm 0:9b334a45a8ff 34 * Code implementation file for the LAN Ethernet interface.
bogdanm 0:9b334a45a8ff 35 */
bogdanm 0:9b334a45a8ff 36
bogdanm 0:9b334a45a8ff 37 #include <stdio.h>
mbed_official 80:bdf1132a57cf 38 #include "wait_api.h"
bogdanm 0:9b334a45a8ff 39 #include "ETH_MPS2.h"
bogdanm 0:9b334a45a8ff 40
bogdanm 0:9b334a45a8ff 41 // SMSC9220 low-level operations
bogdanm 0:9b334a45a8ff 42 unsigned int smsc9220_mac_regread(unsigned char regoffset, unsigned int *data)
bogdanm 0:9b334a45a8ff 43 {
bogdanm 0:9b334a45a8ff 44 unsigned int val, maccmd;
bogdanm 0:9b334a45a8ff 45 int timedout;
bogdanm 0:9b334a45a8ff 46 int error;
bogdanm 0:9b334a45a8ff 47
bogdanm 0:9b334a45a8ff 48 error = 0;
bogdanm 0:9b334a45a8ff 49 val = SMSC9220->MAC_CSR_CMD;
bogdanm 0:9b334a45a8ff 50 if(!(val & ((unsigned int)1 << 31))) { // Make sure there's no pending operation
bogdanm 0:9b334a45a8ff 51 maccmd = 0;
bogdanm 0:9b334a45a8ff 52 maccmd |= regoffset;
bogdanm 0:9b334a45a8ff 53 maccmd |= ((unsigned int)1 << 30); // Indicates read
bogdanm 0:9b334a45a8ff 54 maccmd |= ((unsigned int)1 << 31); // Start bit
bogdanm 0:9b334a45a8ff 55 SMSC9220->MAC_CSR_CMD = maccmd; // Start operation
bogdanm 0:9b334a45a8ff 56
bogdanm 0:9b334a45a8ff 57 timedout = 50;
bogdanm 0:9b334a45a8ff 58 do {
bogdanm 0:9b334a45a8ff 59 val = SMSC9220->BYTE_TEST; // A no-op read.
mbed_official 80:bdf1132a57cf 60 wait_ms(1);
bogdanm 0:9b334a45a8ff 61 timedout--;
bogdanm 0:9b334a45a8ff 62 } while(timedout && (SMSC9220->MAC_CSR_CMD & ((unsigned int)1 << 31)));
bogdanm 0:9b334a45a8ff 63
bogdanm 0:9b334a45a8ff 64 if(!timedout) {
bogdanm 0:9b334a45a8ff 65 error = 1;
bogdanm 0:9b334a45a8ff 66 }
bogdanm 0:9b334a45a8ff 67 else
bogdanm 0:9b334a45a8ff 68 *data = SMSC9220->MAC_CSR_DATA;
bogdanm 0:9b334a45a8ff 69 } else {
bogdanm 0:9b334a45a8ff 70 *data = 0;
bogdanm 0:9b334a45a8ff 71 }
bogdanm 0:9b334a45a8ff 72 return error;
bogdanm 0:9b334a45a8ff 73 }
bogdanm 0:9b334a45a8ff 74
bogdanm 0:9b334a45a8ff 75 unsigned int smsc9220_mac_regwrite(unsigned char regoffset, unsigned int data)
bogdanm 0:9b334a45a8ff 76 {
bogdanm 0:9b334a45a8ff 77 unsigned int read, maccmd;
bogdanm 0:9b334a45a8ff 78 int timedout;
bogdanm 0:9b334a45a8ff 79 int error;
bogdanm 0:9b334a45a8ff 80
bogdanm 0:9b334a45a8ff 81 error = 0;
bogdanm 0:9b334a45a8ff 82 read = SMSC9220->MAC_CSR_CMD;
bogdanm 0:9b334a45a8ff 83 if(!(read & ((unsigned int)1 << 31))) { // Make sure there's no pending operation
bogdanm 0:9b334a45a8ff 84 SMSC9220->MAC_CSR_DATA = data; // Store data.
bogdanm 0:9b334a45a8ff 85 maccmd = 0;
bogdanm 0:9b334a45a8ff 86 maccmd |= regoffset;
bogdanm 0:9b334a45a8ff 87 maccmd &= ~((unsigned int)1 << 30); // Clear indicates write
bogdanm 0:9b334a45a8ff 88 maccmd |= ((unsigned int)1 << 31); // Indicate start of operation
bogdanm 0:9b334a45a8ff 89 SMSC9220->MAC_CSR_CMD = maccmd;
bogdanm 0:9b334a45a8ff 90
bogdanm 0:9b334a45a8ff 91 timedout = 50;
bogdanm 0:9b334a45a8ff 92 do {
bogdanm 0:9b334a45a8ff 93 read = SMSC9220->BYTE_TEST; // A no-op read.
mbed_official 80:bdf1132a57cf 94 wait_ms(1);
bogdanm 0:9b334a45a8ff 95 timedout--;
bogdanm 0:9b334a45a8ff 96 } while(timedout && (SMSC9220->MAC_CSR_CMD & ((unsigned int)1 << 31)));
bogdanm 0:9b334a45a8ff 97
bogdanm 0:9b334a45a8ff 98 if(!timedout) {
bogdanm 0:9b334a45a8ff 99 error = 1;
bogdanm 0:9b334a45a8ff 100 }
bogdanm 0:9b334a45a8ff 101 } else {
bogdanm 0:9b334a45a8ff 102 printf("Warning: SMSC9220 MAC CSR is busy. No data written.\n");
bogdanm 0:9b334a45a8ff 103 }
bogdanm 0:9b334a45a8ff 104 return error;
bogdanm 0:9b334a45a8ff 105 }
bogdanm 0:9b334a45a8ff 106
bogdanm 0:9b334a45a8ff 107 unsigned int smsc9220_phy_regread(unsigned char regoffset, unsigned short *data)
bogdanm 0:9b334a45a8ff 108 {
bogdanm 0:9b334a45a8ff 109 unsigned int val, phycmd; int error;
bogdanm 0:9b334a45a8ff 110 int timedout;
bogdanm 0:9b334a45a8ff 111
bogdanm 0:9b334a45a8ff 112 error = 0;
bogdanm 0:9b334a45a8ff 113
bogdanm 0:9b334a45a8ff 114 smsc9220_mac_regread(SMSC9220_MAC_MII_ACC, &val);
bogdanm 0:9b334a45a8ff 115
bogdanm 0:9b334a45a8ff 116 if(!(val & 1)) { // Not busy
bogdanm 0:9b334a45a8ff 117 phycmd = 0;
bogdanm 0:9b334a45a8ff 118 phycmd |= (1 << 11); // 1 to [15:11]
bogdanm 0:9b334a45a8ff 119 phycmd |= ((regoffset & 0x1F) << 6); // Put regoffset to [10:6]
bogdanm 0:9b334a45a8ff 120 phycmd &= ~(1 << 1); // Clear [1] indicates read.
bogdanm 0:9b334a45a8ff 121 phycmd |= (1 << 0); // Set [0] indicates operation start
bogdanm 0:9b334a45a8ff 122
bogdanm 0:9b334a45a8ff 123 smsc9220_mac_regwrite(SMSC9220_MAC_MII_ACC, phycmd);
bogdanm 0:9b334a45a8ff 124
bogdanm 0:9b334a45a8ff 125 val = 0;
bogdanm 0:9b334a45a8ff 126 timedout = 50;
bogdanm 0:9b334a45a8ff 127 do {
mbed_official 80:bdf1132a57cf 128 wait_ms(1);
bogdanm 0:9b334a45a8ff 129 timedout--;
bogdanm 0:9b334a45a8ff 130 smsc9220_mac_regread(SMSC9220_MAC_MII_ACC,&val);
bogdanm 0:9b334a45a8ff 131 } while(timedout && (val & ((unsigned int)1 << 0)));
bogdanm 0:9b334a45a8ff 132
bogdanm 0:9b334a45a8ff 133 if(!timedout) {
bogdanm 0:9b334a45a8ff 134 error = 1;
bogdanm 0:9b334a45a8ff 135 }
bogdanm 0:9b334a45a8ff 136 else
bogdanm 0:9b334a45a8ff 137 smsc9220_mac_regread(SMSC9220_MAC_MII_DATA, (unsigned int *)data);
bogdanm 0:9b334a45a8ff 138
bogdanm 0:9b334a45a8ff 139 } else {
bogdanm 0:9b334a45a8ff 140 *data = 0;
bogdanm 0:9b334a45a8ff 141 }
bogdanm 0:9b334a45a8ff 142 return error;
bogdanm 0:9b334a45a8ff 143 }
bogdanm 0:9b334a45a8ff 144
bogdanm 0:9b334a45a8ff 145 unsigned int smsc9220_phy_regwrite(unsigned char regoffset, unsigned short data)
bogdanm 0:9b334a45a8ff 146 {
bogdanm 0:9b334a45a8ff 147 unsigned int val, phycmd; int error;
bogdanm 0:9b334a45a8ff 148 int timedout;
bogdanm 0:9b334a45a8ff 149
bogdanm 0:9b334a45a8ff 150 error = 0;
bogdanm 0:9b334a45a8ff 151
bogdanm 0:9b334a45a8ff 152 smsc9220_mac_regread(SMSC9220_MAC_MII_ACC, &val);
bogdanm 0:9b334a45a8ff 153
bogdanm 0:9b334a45a8ff 154 if(!(val & 1)) { // Not busy
bogdanm 0:9b334a45a8ff 155 smsc9220_mac_regwrite(SMSC9220_MAC_MII_DATA, (data & 0xFFFF)); // Load the data
bogdanm 0:9b334a45a8ff 156 phycmd = 0;
bogdanm 0:9b334a45a8ff 157 phycmd |= (1 << 11); // 1 to [15:11]
bogdanm 0:9b334a45a8ff 158 phycmd |= ((regoffset & 0x1F) << 6); // Put regoffset to [10:6]
bogdanm 0:9b334a45a8ff 159 phycmd |= (1 << 1); // Set [1] indicates write.
bogdanm 0:9b334a45a8ff 160 phycmd |= (1 << 0); // Set [0] indicates operation start
bogdanm 0:9b334a45a8ff 161 smsc9220_mac_regwrite(SMSC9220_MAC_MII_ACC, phycmd); // Start operation
bogdanm 0:9b334a45a8ff 162
bogdanm 0:9b334a45a8ff 163 phycmd = 0;
bogdanm 0:9b334a45a8ff 164 timedout = 50;
bogdanm 0:9b334a45a8ff 165
bogdanm 0:9b334a45a8ff 166 do {
bogdanm 0:9b334a45a8ff 167
mbed_official 80:bdf1132a57cf 168 wait_ms(1);
bogdanm 0:9b334a45a8ff 169 timedout--;
bogdanm 0:9b334a45a8ff 170 smsc9220_mac_regread(SMSC9220_MAC_MII_ACC, &phycmd);
bogdanm 0:9b334a45a8ff 171 } while(timedout && (phycmd & (1 << 0)));
bogdanm 0:9b334a45a8ff 172
bogdanm 0:9b334a45a8ff 173 if(!timedout) {
bogdanm 0:9b334a45a8ff 174 error = 1;
bogdanm 0:9b334a45a8ff 175 }
bogdanm 0:9b334a45a8ff 176
bogdanm 0:9b334a45a8ff 177 } else {
bogdanm 0:9b334a45a8ff 178 printf("Warning: SMSC9220 MAC MII is busy. No data written.\n");
bogdanm 0:9b334a45a8ff 179 }
bogdanm 0:9b334a45a8ff 180 return error;
bogdanm 0:9b334a45a8ff 181 }
bogdanm 0:9b334a45a8ff 182
bogdanm 0:9b334a45a8ff 183 // Returns smsc9220 id.
bogdanm 0:9b334a45a8ff 184 unsigned int smsc9220_read_id(void)
bogdanm 0:9b334a45a8ff 185 {
bogdanm 0:9b334a45a8ff 186 return SMSC9220->ID_REV;
bogdanm 0:9b334a45a8ff 187 }
bogdanm 0:9b334a45a8ff 188
bogdanm 0:9b334a45a8ff 189 // Initiates a soft reset, returns failure or success.
bogdanm 0:9b334a45a8ff 190 unsigned int smsc9220_soft_reset(void)
bogdanm 0:9b334a45a8ff 191 {
bogdanm 0:9b334a45a8ff 192 int timedout;
bogdanm 0:9b334a45a8ff 193
bogdanm 0:9b334a45a8ff 194 timedout = 10;
bogdanm 0:9b334a45a8ff 195 // Soft reset
bogdanm 0:9b334a45a8ff 196 SMSC9220->HW_CFG |= 1;
bogdanm 0:9b334a45a8ff 197
bogdanm 0:9b334a45a8ff 198 do {
mbed_official 80:bdf1132a57cf 199 wait_ms(1);
bogdanm 0:9b334a45a8ff 200 timedout--;
bogdanm 0:9b334a45a8ff 201 } while(timedout && (SMSC9220->HW_CFG & 1));
bogdanm 0:9b334a45a8ff 202
bogdanm 0:9b334a45a8ff 203 if(!timedout)
bogdanm 0:9b334a45a8ff 204 return 1;
bogdanm 0:9b334a45a8ff 205
bogdanm 0:9b334a45a8ff 206 return 0;
bogdanm 0:9b334a45a8ff 207 }
bogdanm 0:9b334a45a8ff 208
bogdanm 0:9b334a45a8ff 209 void smsc9220_set_txfifo(unsigned int val)
bogdanm 0:9b334a45a8ff 210 {
bogdanm 0:9b334a45a8ff 211 // 2kb minimum, 14kb maximum
bogdanm 0:9b334a45a8ff 212 if(val < 2 || val > 14)
bogdanm 0:9b334a45a8ff 213 return;
bogdanm 0:9b334a45a8ff 214
bogdanm 0:9b334a45a8ff 215 SMSC9220->HW_CFG = val << 16;
bogdanm 0:9b334a45a8ff 216 }
bogdanm 0:9b334a45a8ff 217
bogdanm 0:9b334a45a8ff 218
bogdanm 0:9b334a45a8ff 219 unsigned int smsc9220_wait_eeprom(void)
bogdanm 0:9b334a45a8ff 220 {
bogdanm 0:9b334a45a8ff 221 int timedout;
bogdanm 0:9b334a45a8ff 222
bogdanm 0:9b334a45a8ff 223 timedout = 50;
bogdanm 0:9b334a45a8ff 224
bogdanm 0:9b334a45a8ff 225 do {
mbed_official 80:bdf1132a57cf 226 wait_ms(1);
bogdanm 0:9b334a45a8ff 227 timedout--;
bogdanm 0:9b334a45a8ff 228
bogdanm 0:9b334a45a8ff 229 } while(timedout && (SMSC9220->E2P_CMD & ((unsigned int) 1 << 31)));
bogdanm 0:9b334a45a8ff 230
bogdanm 0:9b334a45a8ff 231 if(!timedout)
bogdanm 0:9b334a45a8ff 232 return 1;
bogdanm 0:9b334a45a8ff 233
bogdanm 0:9b334a45a8ff 234 return 0;
bogdanm 0:9b334a45a8ff 235 }
bogdanm 0:9b334a45a8ff 236
bogdanm 0:9b334a45a8ff 237 /* initialise irqs */
bogdanm 0:9b334a45a8ff 238 void smsc9220_init_irqs(void)
bogdanm 0:9b334a45a8ff 239 {
mbed_official 80:bdf1132a57cf 240 SMSC9220->INT_EN = 0x0;
mbed_official 80:bdf1132a57cf 241 SMSC9220->INT_STS = 0xFFFFFFFF; // clear all interrupts
mbed_official 80:bdf1132a57cf 242 SMSC9220->IRQ_CFG = 0x22000100; // irq deassertion at 220 usecs and master IRQ enable.
bogdanm 0:9b334a45a8ff 243 }
bogdanm 0:9b334a45a8ff 244
bogdanm 0:9b334a45a8ff 245 unsigned int smsc9220_check_phy(void)
bogdanm 0:9b334a45a8ff 246 {
bogdanm 0:9b334a45a8ff 247 unsigned short phyid1, phyid2;
bogdanm 0:9b334a45a8ff 248
bogdanm 0:9b334a45a8ff 249 smsc9220_phy_regread(SMSC9220_PHY_ID1,&phyid1);
bogdanm 0:9b334a45a8ff 250 smsc9220_phy_regread(SMSC9220_PHY_ID2,&phyid2);
bogdanm 0:9b334a45a8ff 251 return ((phyid1 == 0xFFFF && phyid2 == 0xFFFF) ||
bogdanm 0:9b334a45a8ff 252 (phyid1 == 0x0 && phyid2 == 0x0));
bogdanm 0:9b334a45a8ff 253 }
bogdanm 0:9b334a45a8ff 254
bogdanm 0:9b334a45a8ff 255 unsigned int smsc9220_reset_phy(void)
bogdanm 0:9b334a45a8ff 256 {
bogdanm 0:9b334a45a8ff 257 unsigned short read;
bogdanm 0:9b334a45a8ff 258 int error;
bogdanm 0:9b334a45a8ff 259
bogdanm 0:9b334a45a8ff 260 error = 0;
bogdanm 0:9b334a45a8ff 261 if(smsc9220_phy_regread(SMSC9220_PHY_BCONTROL, &read)) {
bogdanm 0:9b334a45a8ff 262 error = 1;
bogdanm 0:9b334a45a8ff 263 return error;
bogdanm 0:9b334a45a8ff 264 }
bogdanm 0:9b334a45a8ff 265
bogdanm 0:9b334a45a8ff 266 read |= (1 << 15);
bogdanm 0:9b334a45a8ff 267 if(smsc9220_phy_regwrite(SMSC9220_PHY_BCONTROL, read)) {
bogdanm 0:9b334a45a8ff 268 error = 1;
bogdanm 0:9b334a45a8ff 269 return error;
bogdanm 0:9b334a45a8ff 270 }
bogdanm 0:9b334a45a8ff 271 return 0;
bogdanm 0:9b334a45a8ff 272 }
bogdanm 0:9b334a45a8ff 273
bogdanm 0:9b334a45a8ff 274 /* Advertise all speeds and pause capabilities */
bogdanm 0:9b334a45a8ff 275 void smsc9220_advertise_cap(void)
bogdanm 0:9b334a45a8ff 276 {
bogdanm 0:9b334a45a8ff 277 unsigned short aneg_adv;
bogdanm 0:9b334a45a8ff 278 aneg_adv = 0;
bogdanm 0:9b334a45a8ff 279
bogdanm 0:9b334a45a8ff 280
bogdanm 0:9b334a45a8ff 281 smsc9220_phy_regread(SMSC9220_PHY_ANEG_ADV, &aneg_adv);
bogdanm 0:9b334a45a8ff 282 aneg_adv |= 0xDE0;
bogdanm 0:9b334a45a8ff 283
bogdanm 0:9b334a45a8ff 284 smsc9220_phy_regwrite(SMSC9220_PHY_ANEG_ADV, aneg_adv);
bogdanm 0:9b334a45a8ff 285 smsc9220_phy_regread(SMSC9220_PHY_ANEG_ADV, &aneg_adv);
bogdanm 0:9b334a45a8ff 286 return;
bogdanm 0:9b334a45a8ff 287 }
bogdanm 0:9b334a45a8ff 288
bogdanm 0:9b334a45a8ff 289 void smsc9220_establish_link(void)
bogdanm 0:9b334a45a8ff 290 {
bogdanm 0:9b334a45a8ff 291 unsigned short bcr;
bogdanm 0:9b334a45a8ff 292
bogdanm 0:9b334a45a8ff 293 smsc9220_phy_regread(SMSC9220_PHY_BCONTROL, &bcr);
bogdanm 0:9b334a45a8ff 294 bcr |= (1 << 12) | (1 << 9);
bogdanm 0:9b334a45a8ff 295 smsc9220_phy_regwrite(SMSC9220_PHY_BCONTROL, bcr);
bogdanm 0:9b334a45a8ff 296 smsc9220_phy_regread(SMSC9220_PHY_BCONTROL, &bcr);
bogdanm 0:9b334a45a8ff 297
bogdanm 0:9b334a45a8ff 298 {
bogdanm 0:9b334a45a8ff 299 unsigned int hw_cfg;
bogdanm 0:9b334a45a8ff 300
bogdanm 0:9b334a45a8ff 301 hw_cfg = 0;
bogdanm 0:9b334a45a8ff 302 hw_cfg = SMSC9220->HW_CFG;
bogdanm 0:9b334a45a8ff 303
bogdanm 0:9b334a45a8ff 304 hw_cfg &= 0xF0000;
bogdanm 0:9b334a45a8ff 305 hw_cfg |= (1 << 20);
bogdanm 0:9b334a45a8ff 306 SMSC9220->HW_CFG = hw_cfg;
bogdanm 0:9b334a45a8ff 307 }
bogdanm 0:9b334a45a8ff 308
bogdanm 0:9b334a45a8ff 309 return;
bogdanm 0:9b334a45a8ff 310 }
bogdanm 0:9b334a45a8ff 311
bogdanm 0:9b334a45a8ff 312 void smsc9220_enable_xmit(void)
bogdanm 0:9b334a45a8ff 313 {
bogdanm 0:9b334a45a8ff 314 SMSC9220->TX_CFG = 0x2; // Enable trasmission
bogdanm 0:9b334a45a8ff 315 return;
bogdanm 0:9b334a45a8ff 316 }
bogdanm 0:9b334a45a8ff 317
bogdanm 0:9b334a45a8ff 318 void smsc9220_enable_mac_xmit(void)
bogdanm 0:9b334a45a8ff 319 {
bogdanm 0:9b334a45a8ff 320 unsigned int mac_cr;
bogdanm 0:9b334a45a8ff 321
bogdanm 0:9b334a45a8ff 322 mac_cr = 0;
bogdanm 0:9b334a45a8ff 323 smsc9220_mac_regread(SMSC9220_MAC_CR, &mac_cr);
bogdanm 0:9b334a45a8ff 324
bogdanm 0:9b334a45a8ff 325 mac_cr |= (1 << 3); // xmit enable
bogdanm 0:9b334a45a8ff 326 mac_cr |= (1 << 28); // Heartbeat disable
bogdanm 0:9b334a45a8ff 327
bogdanm 0:9b334a45a8ff 328 smsc9220_mac_regwrite(SMSC9220_MAC_CR, mac_cr);
bogdanm 0:9b334a45a8ff 329 return;
bogdanm 0:9b334a45a8ff 330 }
bogdanm 0:9b334a45a8ff 331
bogdanm 0:9b334a45a8ff 332 void smsc9220_enable_mac_recv(void)
bogdanm 0:9b334a45a8ff 333 {
bogdanm 0:9b334a45a8ff 334 unsigned int mac_cr;
bogdanm 0:9b334a45a8ff 335
bogdanm 0:9b334a45a8ff 336 mac_cr = 0;
bogdanm 0:9b334a45a8ff 337 smsc9220_mac_regread(SMSC9220_MAC_CR, &mac_cr);
bogdanm 0:9b334a45a8ff 338 mac_cr |= (1 << 2); // Recv enable
bogdanm 0:9b334a45a8ff 339 smsc9220_mac_regwrite(SMSC9220_MAC_CR, mac_cr);
bogdanm 0:9b334a45a8ff 340
bogdanm 0:9b334a45a8ff 341 return;
bogdanm 0:9b334a45a8ff 342 }
bogdanm 0:9b334a45a8ff 343
bogdanm 0:9b334a45a8ff 344
bogdanm 0:9b334a45a8ff 345 unsigned int smsc9220_check_ready(void)
bogdanm 0:9b334a45a8ff 346 {
bogdanm 0:9b334a45a8ff 347 return !(SMSC9220->PMT_CTRL & 1);
bogdanm 0:9b334a45a8ff 348 }
bogdanm 0:9b334a45a8ff 349
bogdanm 0:9b334a45a8ff 350 /* Generate a soft irq */
bogdanm 0:9b334a45a8ff 351 void smsc9220_set_soft_int(void)
bogdanm 0:9b334a45a8ff 352 {
bogdanm 0:9b334a45a8ff 353 SMSC9220->INT_EN |= 0x80000000;
bogdanm 0:9b334a45a8ff 354 }
bogdanm 0:9b334a45a8ff 355
bogdanm 0:9b334a45a8ff 356 /* clear soft irq */
bogdanm 0:9b334a45a8ff 357 void smsc9220_clear_soft_int(void)
bogdanm 0:9b334a45a8ff 358 {
bogdanm 0:9b334a45a8ff 359 SMSC9220->INT_STS |= 0x80000000;
bogdanm 0:9b334a45a8ff 360 }
bogdanm 0:9b334a45a8ff 361
bogdanm 0:9b334a45a8ff 362
bogdanm 0:9b334a45a8ff 363 unsigned int smsc9220_recv_packet(unsigned int *recvbuf, unsigned int *index)
bogdanm 0:9b334a45a8ff 364 {
bogdanm 0:9b334a45a8ff 365 unsigned int rxfifo_inf; // Tells us the status of rx payload and status fifos.
bogdanm 0:9b334a45a8ff 366 unsigned int rxfifo_stat;
bogdanm 0:9b334a45a8ff 367
bogdanm 0:9b334a45a8ff 368 unsigned int pktsize;
bogdanm 0:9b334a45a8ff 369 unsigned int dwords_to_read;
bogdanm 0:9b334a45a8ff 370
bogdanm 0:9b334a45a8ff 371 rxfifo_inf = SMSC9220->RX_FIFO_INF;
bogdanm 0:9b334a45a8ff 372
bogdanm 0:9b334a45a8ff 373 if(rxfifo_inf & 0xFFFF) { // If there's data
bogdanm 0:9b334a45a8ff 374 rxfifo_stat = SMSC9220->RX_STAT_PORT;
bogdanm 0:9b334a45a8ff 375 if(rxfifo_stat != 0) { // Fetch status of this packet
bogdanm 0:9b334a45a8ff 376 pktsize = ((rxfifo_stat >> 16) & 0x3FFF);
bogdanm 0:9b334a45a8ff 377 if(rxfifo_stat & (1 << 15)) {
bogdanm 0:9b334a45a8ff 378 printf("Error occured during receiving of packets on the bus.\n");
bogdanm 0:9b334a45a8ff 379 return 1;
bogdanm 0:9b334a45a8ff 380 } else {
bogdanm 0:9b334a45a8ff 381 /* Below formula (recommended by SMSC9220 code)
bogdanm 0:9b334a45a8ff 382 * gives 1 more than required. This is perhaps because
bogdanm 0:9b334a45a8ff 383 * a last word is needed for not word aligned packets.
bogdanm 0:9b334a45a8ff 384 */
bogdanm 0:9b334a45a8ff 385 dwords_to_read = (pktsize + 3) >> 2;
bogdanm 0:9b334a45a8ff 386 // PIO copy of data received:
bogdanm 0:9b334a45a8ff 387 while(dwords_to_read > 0) {
bogdanm 0:9b334a45a8ff 388 recvbuf[*index] = SMSC9220->RX_DATA_PORT;
bogdanm 0:9b334a45a8ff 389 (*index)++;
bogdanm 0:9b334a45a8ff 390 dwords_to_read--;
bogdanm 0:9b334a45a8ff 391 }
bogdanm 0:9b334a45a8ff 392 }
bogdanm 0:9b334a45a8ff 393 } else {
bogdanm 0:9b334a45a8ff 394 return 1;
bogdanm 0:9b334a45a8ff 395 }
bogdanm 0:9b334a45a8ff 396 } else {
bogdanm 0:9b334a45a8ff 397 return 1;
bogdanm 0:9b334a45a8ff 398 }
bogdanm 0:9b334a45a8ff 399
bogdanm 0:9b334a45a8ff 400 rxfifo_stat = SMSC9220->RX_STAT_PORT;
bogdanm 0:9b334a45a8ff 401 rxfifo_inf = SMSC9220->RX_FIFO_INF;
bogdanm 0:9b334a45a8ff 402
bogdanm 0:9b334a45a8ff 403 return 0;
bogdanm 0:9b334a45a8ff 404 }
bogdanm 0:9b334a45a8ff 405
bogdanm 0:9b334a45a8ff 406
bogdanm 0:9b334a45a8ff 407 // Does the actual transfer of data to FIFO, note it does no
bogdanm 0:9b334a45a8ff 408 // fifo availability checking. This should be done by caller.
bogdanm 0:9b334a45a8ff 409 // Assumes the whole frame is transferred at once as a single segment
bogdanm 0:9b334a45a8ff 410 void smsc9220_xmit_packet(unsigned char * pkt, unsigned int length)
bogdanm 0:9b334a45a8ff 411 {
bogdanm 0:9b334a45a8ff 412 unsigned int txcmd_a, txcmd_b;
bogdanm 0:9b334a45a8ff 413 unsigned int dwords_to_write;
bogdanm 0:9b334a45a8ff 414 volatile unsigned int dwritten;
bogdanm 0:9b334a45a8ff 415 unsigned int *pktptr;
bogdanm 0:9b334a45a8ff 416 volatile unsigned int xmit_stat, xmit_stat2, xmit_inf;
bogdanm 0:9b334a45a8ff 417 int i;
bogdanm 0:9b334a45a8ff 418
bogdanm 0:9b334a45a8ff 419 pktptr = (unsigned int *) pkt;
bogdanm 0:9b334a45a8ff 420 txcmd_a = 0;
bogdanm 0:9b334a45a8ff 421 txcmd_b = 0;
bogdanm 0:9b334a45a8ff 422
bogdanm 0:9b334a45a8ff 423 txcmd_a |= (1 << 12) | (1 << 13); // First and last segments
bogdanm 0:9b334a45a8ff 424 txcmd_a |= length & 0x7FF; // [10:0] contains length
bogdanm 0:9b334a45a8ff 425
bogdanm 0:9b334a45a8ff 426 txcmd_b |= ((length & 0xFFFF) << 16); // [31:16] contains length
bogdanm 0:9b334a45a8ff 427 txcmd_b |= length & 0x7FF; // [10:0] also contains length
bogdanm 0:9b334a45a8ff 428
bogdanm 0:9b334a45a8ff 429
bogdanm 0:9b334a45a8ff 430 SMSC9220->TX_DATA_PORT = txcmd_a;
bogdanm 0:9b334a45a8ff 431 SMSC9220->TX_DATA_PORT = txcmd_b;
bogdanm 0:9b334a45a8ff 432 dwritten = dwords_to_write = (length + 3) >> 2;
bogdanm 0:9b334a45a8ff 433
bogdanm 0:9b334a45a8ff 434 // PIO Copy to FIFO. Could replace this with DMA.
bogdanm 0:9b334a45a8ff 435 while(dwords_to_write > 0) {
bogdanm 0:9b334a45a8ff 436 SMSC9220->TX_DATA_PORT = *pktptr;
bogdanm 0:9b334a45a8ff 437 pktptr++;
bogdanm 0:9b334a45a8ff 438 dwords_to_write--;
bogdanm 0:9b334a45a8ff 439 }
bogdanm 0:9b334a45a8ff 440
bogdanm 0:9b334a45a8ff 441 xmit_stat = SMSC9220->TX_STAT_PORT;
bogdanm 0:9b334a45a8ff 442 xmit_stat2 = SMSC9220->TX_STAT_PORT;
bogdanm 0:9b334a45a8ff 443 xmit_inf = SMSC9220->TX_FIFO_INF;
bogdanm 0:9b334a45a8ff 444
bogdanm 0:9b334a45a8ff 445 if(xmit_stat2 != 0 ) {
bogdanm 0:9b334a45a8ff 446 for(i = 0; i < 6; i++) {
bogdanm 0:9b334a45a8ff 447 xmit_stat2 = SMSC9220->TX_STAT_PORT;
bogdanm 0:9b334a45a8ff 448 }
bogdanm 0:9b334a45a8ff 449 }
bogdanm 0:9b334a45a8ff 450 }