cc3000 hostdriver with the mbed socket interface
Fork of cc3000_hostdriver_mbedsocket by
Diff: cc3000_spi.cpp
- 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