강좌 & 팁
지난번에는 CC3000의 Smart Config 어플리케이션을 활용하면 편리하게 AP연결하는 방법에 대해 알아보았습니다.
오늘은 CC3000을 MCU에 포팅해보도록 하겠습니다. MCU는 STM32F4로 해보겠습니다.
CC3000은 호스트 MCU와 SPI를 통해서 연결됩니다.
그리고 IRQ 인터럽트(WL_SPI_IRQ_HOST)를 위한 GPIO 하나와
CC3000 모듈의 전원 on/off를 위한 GPIO 포트(VBAT_SW_EN)를 연결합니다.
아래와 같이 연결하면 됩니다.
CC3000의 포팅은 전반적으로 아래와 같은 구조로 진행됩니다.
여기서 stm32와 연결하는 부분은 HCI와 SPI transport layer 부분만 포팅하면 됩니다.
상위의 WLAN API 및 기타 API들은 하드웨어 포팅과는 크게 관련없이 네트워크 프로그래밍을 위해 사용됩니다.
포팅을 위해서는 아래 링크에서 TI에서 제공하는 Basic Wifi Application 소스로 작업할 수 있습니다.
설치를 하고 나면 설치된 경로에 예제 소스가 함께 있는데 그중에서 CC3000HostDriver와 CC3000 Spi 폴더를
stm32 프로젝트로 복사합니다. 그리고 BasicWifiApplication폴더는 포팅을 위해 참고만 합니다.
stm32 프로젝트 폴더에 복사한 뒤 디렉토리 구조입니다.
여기서 HostDriver 부분은 포팅을 위해 거의 수정할 부분이 없습니다. 주로 CC3000_spi폴더에서 수정합니다.
spi.c에서 아래 SPI와 GPIO 초기화 부분만 stm32로 포팅하고 SpiWriteDataSynchronous(), SpiReadDataSynchronous()를 수정합니다.
그리고 CC3000 IRQ 세팅을 위한 IntSpiGPIOHandler()도 stm32에 맞게 수정합니다.
아래는 stm32f4와 연결하기 위해 수정한 spi.c의 함수들입니다.
void pio_init()
{
GPIO_InitTypeDef GPIO_InitStructure;
/* CC3000_WIFI_CS_GPIO and CC3000_WIFI_EN_GPIO Peripheral clock enable */
RCC_AHB1PeriphClockCmd(CC3000_WIFI_CS_GPIO_CLK | CC3000_WIFI_EN_GPIO_CLK, ENABLE);
/* Configure CC3000_WIFI pins: CS output push-pull mode */
GPIO_InitStructure.GPIO_Pin = CC3000_WIFI_CS_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//GPIO_PuPd_NOPULL;
GPIO_Init(CC3000_WIFI_CS_GPIO_PORT, &GPIO_InitStructure);
/* Configure CC3000_WIFI pins: Enable */
GPIO_InitStructure.GPIO_Pin = CC3000_WIFI_EN_GPIO_PIN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//GPIO_PuPd_UP;//GPIO_PuPd_NOPULL;
GPIO_Init(CC3000_WIFI_EN_GPIO_PORT, &GPIO_InitStructure);
/* Disable CC3000 */
CC3000_Write_Enable_Pin(WLAN_ENABLE);//WiFi is enabled...
/* Deselect CC3000 */
CC3000_CS_HIGH();
CC3000_Interrupt_Enable();
}
CC3000의 IRQ를 위해 stm32의 EXTI 인터럽트를 초기화 합니다.
void CC3000_Interrupt_Enable(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* CC3000_WIFI_INT_GPIO and AFIO Peripheral clock enable */
RCC_AHB1PeriphClockCmd(CC3000_WIFI_INT_GPIO_CLK, ENABLE);
/* Enable SYSCFG clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //ported from stm32f4xx stdperiph lib
/* Configure CC3000_WIFI pins: Interrupt */
//ported from stm32f4xx stdperiph lib
GPIO_InitStructure.GPIO_Pin = CC3000_WIFI_INT_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//GPIO_PuPd_NOPULL;
GPIO_Init(CC3000_WIFI_INT_GPIO_PORT, &GPIO_InitStructure);
/* Select the CC3000_WIFI_INT GPIO pin used as EXTI Line */
/* Connect EXTI Line12 to PD12 pin */
SYSCFG_EXTILineConfig(CC3000_WIFI_INT_EXTI_PORT_SOURCE, CC3000_WIFI_INT_EXTI_PIN_SOURCE);//ported from stm32f4xx stdperiph lib
/* Clear the EXTI line pending flag */
EXTI_ClearFlag(CC3000_WIFI_INT_EXTI_LINE);
/* Configure and Enable CC3000_WIFI_INT EXTI line */
EXTI_InitStructure.EXTI_Line = CC3000_WIFI_INT_EXTI_LINE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set CC3000_WIFI_INT EXTI Interrupt to the lowest priority */
NVIC_InitStructure.NVIC_IRQChannel = CC3000_WIFI_INT_EXTI_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EXTI15_10_IRQ_PRIORITY; //OLD: 0x00
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //OLD: 0x01
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
int init_spi(void) {
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//DMA_InitTypeDef DMA_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
/* Peripheral Clock Enable -------------------------------------------------*/
/* Enable the SPI clock */
SPIx_CLK_INIT(SPIx_CLK, ENABLE);
/* Enable GPIO clocks */
RCC_AHB1PeriphClockCmd(
SPIx_SCK_GPIO_CLK | SPIx_MISO_GPIO_CLK | SPIx_MOSI_GPIO_CLK,
ENABLE);
/* SPI GPIO Configuration --------------------------------------------------*/
/* GPIO Deinitialisation */
GPIO_DeInit(SPIx_SCK_GPIO_PORT);
GPIO_DeInit(SPIx_MISO_GPIO_PORT);
GPIO_DeInit(SPIx_MOSI_GPIO_PORT);
/* Connect SPI pins to AF5 */
GPIO_PinAFConfig(SPIx_SCK_GPIO_PORT, SPIx_SCK_SOURCE, SPIx_SCK_AF);
GPIO_PinAFConfig(SPIx_MISO_GPIO_PORT, SPIx_MISO_SOURCE, SPIx_MISO_AF);
GPIO_PinAFConfig(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_SOURCE, SPIx_MOSI_AF);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
/* SPI SCK pin configuration */
GPIO_InitStructure.GPIO_Pin = SPIx_SCK_PIN;
GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStructure);
/* SPI MISO pin configuration */
GPIO_InitStructure.GPIO_Pin = SPIx_MISO_PIN;
GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStructure);
/* SPI MOSI pin configuration */
GPIO_InitStructure.GPIO_Pin = SPIx_MOSI_PIN;
GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStructure);
/* SPI configuration -------------------------------------------------------*/
SPI_I2S_DeInit(SPIx);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;//SPI_BaudRatePrescaler_32;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_Init(SPIx, &SPI_InitStructure);
/* Enable the SPI peripheral */
SPI_Cmd(SPIx, ENABLE);
}
- Screenshot from 2014-11-29 16:31:22.png (24.4KB)(155)
- Screenshot from 2014-11-29 16:32:01.png (15.6KB)(147)
- Screenshot from 2014-11-29 16:42:59.png (24.8KB)(121)
- Screenshot from 2014-11-29 16:46:36.png (43.7KB)(116)
- Screenshot from 2014-11-29 16:52:19.png (10.5KB)(120)
- Screenshot from 2014-11-29 16:53:36.png (27.0KB)(169)