added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
80:bdf1132a57cf
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

Who changed what in which revision?

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