ZG2100 Network interface source

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers zg_drv.c Source File

zg_drv.c

00001 
00002 /*
00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
00004  
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to deal
00007 in the Software without restriction, including without limitation the rights
00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009 copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011  
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014  
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021 THE SOFTWARE.
00022 */
00023 
00024 #include "netCfg.h"
00025 #if NET_ZG2100
00026 
00027 #include "zg_defs.h"
00028 #include "zg_err.h"
00029 #include "zg_drv.h"
00030 #include "zg_com.h"
00031 
00032 //#define __DEBUG
00033 #include "dbg/dbg.h"
00034 
00035 #include "mbed.h"
00036 byte head_buf[ZG_HEAD_BUF_SIZE] ZG_MEM;
00037 byte fifo_buf[ZG_FIFO_BUF_SIZE] ZG_MEM; //Big buffer used for fifo transfers
00038 static volatile bool int_raised;
00039 static bool mgmt_busy; //Processing a req
00040 static int tx_pending; //Packet sent but not acked yet
00041 static bool connected; //Connected to a wifi network
00042 ZG_DATA zg_data; //Container for all data received from the chip
00043 ZG_DATA_MASK zg_data_mask; //Flags valid data
00044 static uint32_t current_mgmt_param;
00045 
00046 //Spi intf, Chip Select pin, Interrupt pin
00047 zg_err zg_drv_init()
00048 {
00049   word sys_version;
00050   int_raised = false;
00051   memset((void*)&zg_data, 0, sizeof(ZG_DATA));
00052   memset((void*)&zg_data_mask, 0, sizeof(ZG_DATA_MASK));
00053   current_mgmt_param = 0;
00054   mgmt_busy = false;
00055   tx_pending = 0;
00056   connected = false;
00057   
00058   //Reset
00059   zg_indexed_register_write(ZG_IREG_HW_RST, 0x80FF);
00060   zg_indexed_register_write(ZG_IREG_HW_RST, 0x0FFF);
00061   
00062   DBG("Started reset\n");
00063   
00064   while( !(zg_indexed_register_read(ZG_IREG_HW_STATUS) & ZG_HW_STATUS_RESET) )
00065   {
00066     ;
00067   }
00068 
00069   DBG("Stopped\n");
00070   
00071   while( zg_register_read(ZG_REG_F0_ROOM) == 0 )
00072   {
00073     ;
00074   }  
00075   
00076   DBG("Started!\n");
00077   
00078   //Reset OK
00079   
00080   //Setup interrupts
00081   zg_register_write(ZG_REG_INTF, 0);
00082   zg_register_write(ZG_REG_INTE, ZG_INT_MASK_F0 | ZG_INT_MASK_F1);
00083 
00084   zg_register_write(ZG_REG_INTF2, 0xff);
00085   zg_register_write(ZG_REG_INTE2, 0);
00086   
00087   //Read firmware version : FIXME
00088   
00089   zg_register_write(ZG_REG_SYSINFO_INDEX, 0);
00090   
00091   sys_version = zg_register_read(ZG_REG_SYSINFO) << 8;
00092   sys_version |= zg_register_read(ZG_REG_SYSINFO) & 0xFF;
00093   
00094   DBG("System Version : %04x\n", sys_version);
00095   
00096   DBG("Setup region\n");
00097   //Setup region
00098   fifo_buf[0] = ZG_REGION;
00099   zg_mgmt_set_param(ZG_FIFO_MGMT_PARM_REGION, fifo_buf, 1);
00100   
00101   while( zg_mgmt_is_busy() )
00102   {
00103     zg_process();
00104   }
00105     
00106   return ZG_OK;
00107 }
00108 
00109 void zg_on_data_attach( void (*on_data)() )
00110 {
00111 
00112 }
00113 
00114 void zg_process() //Must be called regularly by user
00115 {
00116   if( /*int_raised*/ zg_is_int() )
00117   {
00118     //DBG("Processing int\n");
00119     zg_int_process();
00120     int_raised = false;
00121   }
00122 
00123 }
00124 
00125 void zg_int_process()
00126 {
00127   uint32_t int_reg;
00128   int fifo;
00129   int len;
00130   
00131   byte type;
00132   byte subtype;
00133   
00134   /*while(true) //Multiple interrupts might have been raised, loop until the interrupt register is blank
00135   {*/
00136     int_reg = zg_register_read(ZG_REG_INTF) & zg_register_read(ZG_REG_INTE); //Read Masked Interrupt reg
00137     if( int_reg & ZG_INT_MASK_F0 )
00138     {
00139       fifo = 0;
00140     }
00141     else if( int_reg & ZG_INT_MASK_F1 )
00142     {
00143       fifo = 1;
00144     }
00145     else
00146     {
00147       return;
00148     }
00149     
00150     zg_register_write(ZG_REG_INTF, ZG_INT_MASK_F(fifo)); //Select that FIFO ?
00151     
00152     len = zg_register_read(ZG_REG_F_LEN(fifo)) & 0xFFF; //Only 12 lower level bits represent length
00153     
00154     zg_fifo_read(ZG_FIFO_ANY, &type, &subtype, fifo_buf, len);
00155     
00156     //Dispatch this packet
00157     
00158     switch( type )
00159     {
00160     case ZG_FIFO_RD_TXD_ACK:
00161       //DBG("TX ACK\n");
00162       //Packet has been transmitted, we can send another one
00163       tx_pending--;
00164       break;
00165     case ZG_FIFO_RD_RXD_AVL:
00166       //DBG("RX AVL\n");
00167       //Received a packet, process it
00168       zg_on_input(fifo_buf, len); //On reception of a ZG frame : convert into Eth frame & call zg_input
00169       break;
00170     case ZG_FIFO_RD_MGMT_AVL:
00171       zg_on_mgmt_avl(subtype, fifo_buf, len);
00172       mgmt_busy = false; //We can now do another mgmt req
00173       break;
00174     case ZG_FIFO_RD_MGMT_EVT:
00175       zg_on_mgmt_evt(subtype, fifo_buf, len);
00176       break;
00177     default:
00178       DBG("Int processed with type %d\n", type);
00179       //Unknown type
00180       //continue;
00181       break;
00182     }
00183   /*}*/
00184 }
00185 
00186 bool zg_mgmt_is_busy()
00187 {
00188   return mgmt_busy;
00189 }
00190 
00191 void zg_mgmt_req(byte subtype, byte* buf, int len, bool close /*= true*/)
00192 {
00193   zg_fifo_write( ZG_FIFO_MGMT, ZG_FIFO_WR_MGMT_REQ, subtype, buf, len, true, close);
00194   mgmt_busy = true;
00195 }
00196 
00197 void zg_mgmt_data(byte* buf, int len, bool close /*= true*/)
00198 {
00199   zg_fifo_write( ZG_FIFO_MGMT, ZG_FIFO_WR_MGMT_REQ, 0/*subtype: do not care*/, buf, len, false, close);
00200 }
00201 
00202 void zg_mgmt_get_param(byte param)
00203 {
00204   head_buf[0] = 0;
00205   head_buf[1] = param;
00206   zg_mgmt_req( ZG_FIFO_MGMT_PARM_GET, head_buf, 2 );
00207   current_mgmt_param = param;
00208 }
00209 
00210 void zg_mgmt_set_param(byte param, byte* buf, int len)
00211 {
00212   head_buf[0] = 0;
00213   head_buf[1] = param;
00214   zg_mgmt_req( ZG_FIFO_MGMT_PARM_SET, head_buf, 2, false );
00215   zg_mgmt_data( buf, len );
00216   current_mgmt_param = param;
00217 }
00218 
00219 void zg_on_mgmt_avl(byte subtype, byte* buf, int len) //Data is available
00220 {
00221   DBG("Management result, subtype %d\n", subtype);
00222   switch(subtype)
00223   {
00224   case ZG_FIFO_MGMT_SCAN: //Scan results
00225     zg_on_scan_results(buf, len);
00226     break;
00227     
00228   case ZG_FIFO_MGMT_PSK_CALC: //Compute PSK Key
00229     zg_on_psk_key(buf, len);
00230     break;
00231   case ZG_FIFO_MGMT_PMK_KEY: 
00232     break;
00233   case ZG_FIFO_MGMT_WEP_KEY:
00234     break;
00235 
00236   case ZG_FIFO_MGMT_PARM_SET:
00237     DBG("Param set\n");
00238     break;
00239   case ZG_FIFO_MGMT_PARM_GET:
00240     zg_on_mgmt_get_param(buf,len);
00241     break;
00242   case ZG_FIFO_MGMT_ADHOC:
00243     break;
00244   case ZG_FIFO_MGMT_CONNECT:
00245     DBG("Connect result %d, MAC status is %d\n", buf[0], buf[1]);
00246     zg_on_connect(zg_errcode((ZG_INT_ERR)buf[0]));
00247     connected = true;
00248     break;  
00249   case ZG_FIFO_MGMT_CONN_MGMT:
00250     break;
00251   default:
00252     break;
00253   }
00254 }
00255 
00256 void zg_on_mgmt_evt(byte subtype, byte* buf, int len) //Management event
00257 {
00258   DBG("Management event, subtype %d\n", subtype);
00259   switch(subtype)
00260   {
00261   case ZG_FIFO_MGMT_DISASSOC:
00262   case ZG_FIFO_MGMT_DEAUTH:
00263     DBG("Disconnected\n");
00264     connected = false;
00265     break;
00266   case ZG_FIFO_MGMT_CONN:
00267     DBG("Connection status %d\n", DTOHS( *((word*)&buf[0]) ) );
00268     break;
00269     
00270   default:
00271     break;
00272   }
00273 }
00274 
00275 void zg_on_mgmt_get_param(byte* buf, int len)
00276 {
00277   if(buf[0] != 1 /*Success*/)
00278   {
00279     return;
00280   }
00281   buf+=4; //4-byte header
00282   len-=4;
00283   switch(current_mgmt_param)
00284   {
00285   case ZG_FIFO_MGMT_PARM_MACAD: //6 bytes len
00286     memcpy((void*)&zg_data.mac_addr, (void*)buf, ZG_MACADDR_LEN);
00287     zg_data_mask.mac_addr = true;
00288     DBG("HW Addr is : %02x:%02x:%02x:%02x:%02x:%02x.\n", 
00289     zg_data.mac_addr[0], zg_data.mac_addr[1], zg_data.mac_addr[2],
00290     zg_data.mac_addr[3], zg_data.mac_addr[4], zg_data.mac_addr[5]);
00291     break;
00292   case ZG_FIFO_MGMT_PARM_SYSV: //2 bytes len
00293     memcpy((void*)&zg_data.sys_version, (void*)buf, 2);
00294     DBG("Sys version: ROM: %02x; Patch: %02x\n",
00295     zg_data.sys_version.rom, zg_data.sys_version.revision);
00296     zg_data_mask.sys_version = true;  
00297     break;
00298   case ZG_FIFO_MGMT_PARM_REGION:
00299     DBG("Region %d\n", buf[0]);
00300     break;
00301   default:
00302     break;
00303   } 
00304   current_mgmt_param = 0;
00305 }
00306 
00307 //uint32_t zg_fifo_room();
00308 
00309 void zg_on_int() //On data available interrupt
00310 {
00311   int_raised = true;
00312 }
00313 
00314 //Useful to be split in several function because Lwip stores buffers in chunks
00315 void zg_send_start()
00316 {
00317   tx_pending++;
00318   zg_fifo_write( ZG_FIFO_DATA, ZG_FIFO_WR_TXD_REQ, ZG_FIFO_TXD_STD, NULL, 0, true, false ); //Open fifo but does not close it
00319 }
00320 
00321 void zg_send(byte* buf, int len)
00322 {
00323   zg_fifo_write( ZG_FIFO_DATA, ZG_FIFO_WR_TXD_REQ, ZG_FIFO_TXD_STD, buf, len, false, false );
00324 }
00325 
00326 void zg_send_end()
00327 {
00328   zg_fifo_write( ZG_FIFO_DATA, ZG_FIFO_WR_TXD_REQ, ZG_FIFO_TXD_STD, NULL, 0, false, true ); //Close fifo
00329 }
00330 
00331 bool zg_send_is_busy()
00332 {
00333   if( (tx_pending >= ZG_MAX_TX_PENDING) )
00334   {
00335     DBG("Tx is busy...\n");
00336     return true;
00337   }
00338   return false;
00339 }
00340 
00341 #endif