cc3000 hostdriver with the mbed socket interface

Fork of cc3000_hostdriver_mbedsocket by Martin Kojtal

Revision:
45:50ab13d8f2dc
Parent:
44:960b73df5981
Child:
49:aee80f12ccca
--- a/cc3000_spi.cpp	Sun Oct 13 11:46:21 2013 +0200
+++ b/cc3000_spi.cpp	Wed Nov 06 17:56:25 2013 +0100
@@ -43,17 +43,16 @@
 
 namespace mbed_cc3000 {
 
-cc3000_spi::cc3000_spi(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, IRQn_Type irq_port, cc3000_event &event, cc3000_simple_link &simple_link)
-  : _wlan_irq(cc3000_irq), _wlan_en(cc3000_en), _wlan_cs(cc3000_cs), _wlan_spi(cc3000_spi), _irq_port(irq_port),
-    _event(event), _simple_link(simple_link) {
-    /* TODO = clear pending interrupts for PORTS. This is dependent on the used chip */
+cc3000_spi::cc3000_spi(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, cc3000_event &event, cc3000_simple_link &simple_link)
+  : _wlan_irq(cc3000_irq), _wlan_en(cc3000_en), _wlan_cs(cc3000_cs), _wlan_spi(cc3000_spi), _event(event), _simple_link(simple_link) {
 
     _wlan_spi.format(8,1);
     _wlan_spi.frequency(12000000);
-    _function_pointer =  _wlan_irq.fall(this, &cc3000_spi::WLAN_IRQHandler);
+    _wlan_irq.fall(this, &cc3000_spi::WLAN_IRQHandler);
 
     _wlan_en = 0;
     _wlan_cs = 1;
+    wait_ms(50); /* mbed board delay */
 }
 
 cc3000_spi::~cc3000_spi() {
@@ -62,15 +61,17 @@
 
 void cc3000_spi::wlan_irq_enable()
 {
-    NVIC_EnableIRQ(_irq_port);
+    _process_irq = true;
+    //_wlan_irq.enable_irq();
 
-    if(wlan_irq_read() == 0) {
+    if (wlan_irq_read() == 0) {
         WLAN_IRQHandler();
     }
 }
 
 void cc3000_spi::wlan_irq_disable() {
-    NVIC_DisableIRQ(_irq_port);
+    _process_irq = false;
+    //_wlan_irq.disable_irq();
 }
 
 uint32_t cc3000_spi::wlan_irq_read() {
@@ -105,123 +106,106 @@
 
 uint32_t cc3000_spi::write(uint8_t *buffer, uint16_t length) {
     uint8_t pad = 0;
- // check the total length of the packet in order to figure out if padding is necessary
-   if(!(length & 0x0001))
-   {
+    // check the total length of the packet in order to figure out if padding is necessary
+    if(!(length & 0x0001)) {
       pad++;
-   }
-   buffer[0] = WRITE;
-   buffer[1] = HI(length + pad);
-   buffer[2] = LO(length + pad);
-   buffer[3] = 0;
-   buffer[4] = 0;
-
-   length += (SPI_HEADER_SIZE + pad);
+    }
+    buffer[0] = WRITE;
+    buffer[1] = HI(length + pad);
+    buffer[2] = LO(length + pad);
+    buffer[3] = 0;
+    buffer[4] = 0;
 
-   // The magic number resides at the end of the TX/RX buffer (1 byte after the allocated size)
-   // If the magic number is overwitten - buffer overrun occurred - we will be stuck here forever!
-   uint8_t * transmit_buffer = _simple_link.get_transmit_buffer();
-   if (transmit_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
-   {
-      while (1);
-   }
+    length += (SPI_HEADER_SIZE + pad);
 
-   if (_spi_info.spi_state == eSPI_STATE_POWERUP)
-   {
-      while (_spi_info.spi_state != eSPI_STATE_INITIALIZED);
-   }
+    // The magic number resides at the end of the TX/RX buffer (1 byte after the allocated size)
+    // If the magic number is overwitten - buffer overrun occurred - we will be stuck here forever!
+    uint8_t *transmit_buffer = _simple_link.get_transmit_buffer();
+    if (transmit_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) {
+        while (1);
+    }
+
+    if (_spi_info.spi_state == eSPI_STATE_POWERUP) {
+        while (_spi_info.spi_state != eSPI_STATE_INITIALIZED);
+    }
 
-   if (_spi_info.spi_state == eSPI_STATE_INITIALIZED)
-   {
-      // TX/RX transaction over SPI after powerup: IRQ is low - send read buffer size command
-      first_write(buffer, length);
-   }
-   else
-   {
-      // Prevent occurence of a race condition when 2 back to back packets are sent to the
-      // device, so the state will move to IDLE and once again to not IDLE due to IRQ
-      wlan_irq_disable();
+    if (_spi_info.spi_state == eSPI_STATE_INITIALIZED) {
+        // TX/RX transaction over SPI after powerup: IRQ is low - send read buffer size command
+        first_write(buffer, length);
+    } else {
+        // Prevent occurence of a race condition when 2 back to back packets are sent to the
+        // device, so the state will move to IDLE and once again to not IDLE due to IRQ
+        wlan_irq_disable();
 
-      while (_spi_info.spi_state != eSPI_STATE_IDLE);
+        while (_spi_info.spi_state != eSPI_STATE_IDLE);
 
-      _spi_info.spi_state = eSPI_STATE_WRITE_IRQ;
-      //_spi_info.pTxPacket = buffer;
-      _spi_info.tx_packet_length = length;
+        _spi_info.spi_state = eSPI_STATE_WRITE_IRQ;
+        //_spi_info.pTxPacket = buffer;
+        _spi_info.tx_packet_length = length;
 
-      // Assert the CS line and wait until the IRQ line is active, then initialize the write operation
-      _wlan_cs = 0;
+        // Assert the CS line and wait until the IRQ line is active, then initialize the write operation
+        _wlan_cs = 0;
 
-      wlan_irq_enable();
-   }
+        wlan_irq_enable();
+    }
 
-   // Wait until the transaction ends
-   while (_spi_info.spi_state != eSPI_STATE_IDLE);
+    // Wait until the transaction ends
+    while (_spi_info.spi_state != eSPI_STATE_IDLE);
 
-   return 0;
+    return 0;
 }
 
 void cc3000_spi::write_synchronous(uint8_t *data, uint16_t size) {
-   while(size)
-   {
+    while(size) {
         _wlan_spi.write(*data++);
         size--;
-   }
+    }
 }
 
 void cc3000_spi::read_synchronous(uint8_t *data, uint16_t size) {
-   for (uint32_t i = 0; i < size; i++)
-   {
-        data[i] = _wlan_spi.write(0x03);;
-   }
+    for (uint32_t i = 0; i < size; i++) {
+        data[i] = _wlan_spi.write(0x03);
+    }
 }
 
 uint32_t cc3000_spi::read_data_cont() {
-   long data_to_recv;
-   unsigned char *evnt_buff, type;
+   int32_t data_to_recv;
+   uint8_t *evnt_buff, type;
 
    //determine the packet type
    evnt_buff = _simple_link.get_received_buffer();
    data_to_recv = 0;
    STREAM_TO_UINT8((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type);
 
-    switch(type)
-    {
+    switch(type) {
         case HCI_TYPE_DATA:
-        {
-         // Read the remaining data..
-         STREAM_TO_UINT16((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_DATA_LENGTH_OFFSET, data_to_recv);
-         if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1))
-         {
-              data_to_recv++;
-         }
+            // Read the remaining data..
+            STREAM_TO_UINT16((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_DATA_LENGTH_OFFSET, data_to_recv);
+            if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1)) {
+               data_to_recv++;
+            }
 
-         if (data_to_recv)
-         {
+            if (data_to_recv) {
                read_synchronous(evnt_buff + 10, data_to_recv);
-         }
+            }
             break;
-        }
         case HCI_TYPE_EVNT:
-        {
-         // Calculate the rest length of the data
+            // Calculate the rest length of the data
             STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_EVENT_LENGTH_OFFSET, data_to_recv);
-         data_to_recv -= 1;
-         // Add padding byte if needed
-         if ((HEADERS_SIZE_EVNT + data_to_recv) & 1)
-         {
-               data_to_recv++;
-         }
+            data_to_recv -= 1;
+            // Add padding byte if needed
+            if ((HEADERS_SIZE_EVNT + data_to_recv) & 1) {
+                 data_to_recv++;
+            }
 
-         if (data_to_recv)
-         {
+            if (data_to_recv) {
                read_synchronous(evnt_buff + 10, data_to_recv);
-         }
+            }
 
-         _spi_info.spi_state = eSPI_STATE_READ_EOT;
+            _spi_info.spi_state = eSPI_STATE_READ_EOT;
             break;
-        }
     }
-    return (0);
+    return 0;
 }
 
 void cc3000_spi::set_wlan_en(uint8_t value) {
@@ -233,44 +217,39 @@
 }
 
 void cc3000_spi::WLAN_IRQHandler() {
-   if (_spi_info.spi_state == eSPI_STATE_POWERUP)
-   {
-      // Inform HCI Layer that IRQ occured after powerup
-      _spi_info.spi_state = eSPI_STATE_INITIALIZED;
-   }
-   else if (_spi_info.spi_state == eSPI_STATE_IDLE)
-   {
-      _spi_info.spi_state = eSPI_STATE_READ_IRQ;
-      /* IRQ line goes low - acknowledge it */
-       _wlan_cs = 0;
-      read_synchronous(_simple_link.get_received_buffer(), 10);
-      _spi_info.spi_state = eSPI_STATE_READ_EOT;
-
+    if (_process_irq) {
+        if (_spi_info.spi_state == eSPI_STATE_POWERUP) {
+            // Inform HCI Layer that IRQ occured after powerup
+            _spi_info.spi_state = eSPI_STATE_INITIALIZED;
+        } else if (_spi_info.spi_state == eSPI_STATE_IDLE) {
+            _spi_info.spi_state = eSPI_STATE_READ_IRQ;
+            /* IRQ line goes low - acknowledge it */
+             _wlan_cs = 0;
+            read_synchronous(_simple_link.get_received_buffer(), 10);
+            _spi_info.spi_state = eSPI_STATE_READ_EOT;
 
-      // The header was read - continue with the payload read
-      if (!read_data_cont())
-      {
-          // All the data was read - finalize handling by switching to the task
-          // Trigger Rx processing
-          wlan_irq_disable();
-          _wlan_cs = 1;
-          // The magic number resides at the end of the TX/RX buffer (1 byte after the allocated size)
-          // If the magic number is overwitten - buffer overrun occurred - we will be stuck here forever!
-          uint8_t *received_buffer = _simple_link.get_received_buffer();
-          if (received_buffer[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
-              {
-                  while (1);
-              }
-              _spi_info.spi_state = eSPI_STATE_IDLE;
-              _event.received_handler(received_buffer + SPI_HEADER_SIZE);
-      }
-   }
-   else if (_spi_info.spi_state == eSPI_STATE_WRITE_IRQ)
-   {
-      write_synchronous(_simple_link.get_transmit_buffer(), _spi_info.tx_packet_length);
-      _spi_info.spi_state = eSPI_STATE_IDLE;
-      _wlan_cs = 1;
-   }
+            // The header was read - continue with the payload read
+            if (!read_data_cont()) {
+                // All the data was read - finalize handling by switching to the task
+                // Trigger Rx processing
+                wlan_irq_disable();
+                _wlan_cs = 1;
+                // The magic number resides at the end of the TX/RX buffer (1 byte after the allocated size)
+                // If the magic number is overwitten - buffer overrun occurred - we will be stuck here forever!
+                uint8_t *received_buffer = _simple_link.get_received_buffer();
+                if (received_buffer[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) {
+                    while (1);
+                }
+
+                _spi_info.spi_state = eSPI_STATE_IDLE;
+                _event.received_handler(received_buffer + SPI_HEADER_SIZE);
+            }
+        } else if (_spi_info.spi_state == eSPI_STATE_WRITE_IRQ) {
+            write_synchronous(_simple_link.get_transmit_buffer(), _spi_info.tx_packet_length);
+            _spi_info.spi_state = eSPI_STATE_IDLE;
+            _wlan_cs = 1;
+        }
+    }
 }
 
-}
+} // namespace mbed_cc3000