mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-01 13:10:43 +00:00
134 lines
3.5 KiB
C
134 lines
3.5 KiB
C
#include "mongoose.h"
|
|
#include "main.h"
|
|
|
|
#define WIFISPI SPI1
|
|
|
|
#ifndef WIFI_NAME
|
|
#define WIFI_NAME ""
|
|
#endif
|
|
|
|
#ifndef WIFI_PASS
|
|
#define WIFI_PASS ""
|
|
#endif
|
|
|
|
#ifndef WIFI_AP_NAME
|
|
#define WIFI_AP_NAME "Mongoose"
|
|
#endif
|
|
|
|
#ifndef WIFI_AP_PASS
|
|
#define WIFI_AP_PASS "mongoose"
|
|
#endif
|
|
|
|
#ifndef ENABLE_WIFI_AP
|
|
#define ENABLE_WIFI_AP 0
|
|
#endif
|
|
|
|
#define BIT(x) (1UL << (x))
|
|
#define CLRSET(reg, clear, set) ((reg) = ((reg) & ~(clear)) | (set))
|
|
|
|
static inline void spin(volatile uint32_t n) {
|
|
while (n--)
|
|
(void)0;
|
|
}
|
|
|
|
static inline void hal_spi_init(SPI_TypeDef *spi, uint16_t div) {
|
|
(void)spi;
|
|
uint32_t br = 0; // Baud rate prescaler: div = 2,4,8...256 -> MBR = 0..7
|
|
while (div > 2)
|
|
div >>= 1, br++;
|
|
if (br > 7)
|
|
br = 7;
|
|
|
|
|
|
CLRSET(RCC->CCIPR1, 3 << 20, 1); // SYSCLK source
|
|
RCC->APB2ENR |= BIT(12); // SPI1EN
|
|
spin(100);
|
|
spi->CR1 = 0; // disable SPI
|
|
spi->CR1 = SPI_CR1_SSI_Msk; // SSI
|
|
spi->CFG1 = (7 << SPI_CFG1_DSIZE_Pos) | (br << SPI_CFG1_MBR_Pos); // DSIZE = 8-bit, MBR
|
|
spi->CFG2 = SPI_CFG2_SSM_Msk | SPI_CFG2_MASTER_Msk;
|
|
spi->CR1 |= SPI_CR1_SPE_Msk; // Enable SPI
|
|
spi->CR1 |= SPI_CR1_CSTART_Msk; // Start transfer
|
|
}
|
|
|
|
static inline uint8_t hal_spi_xfer_byte(SPI_TypeDef *spi, uint8_t byte) {
|
|
(void)spi;
|
|
while ((spi->SR & SPI_SR_TXP_Msk) == 0)
|
|
spin(1); // TXP
|
|
*(volatile uint8_t *) &spi->TXDR = byte;
|
|
while (((spi->SR & SPI_SR_RXP_Msk) == 0) && ((spi->SR & SPI_SR_RXWNE_Msk) == 0) && ((spi->SR & SPI_SR_RXPLVL_Msk) == 0))
|
|
spin(1); // RXP
|
|
uint8_t rx = *(volatile uint8_t *) &spi->RXDR;
|
|
return rx;
|
|
}
|
|
|
|
static inline void hal_spi_tx_rx(SPI_TypeDef *spi, uint8_t *tx, uint8_t *rx, size_t len) {
|
|
for (size_t i = 0; i < len; i++) {
|
|
uint8_t rx_ = hal_spi_xfer_byte(spi, tx ? tx[i] : 0);
|
|
if (rx) rx[i] = rx_;
|
|
}
|
|
}
|
|
|
|
static inline bool hal_spi_ready(SPI_TypeDef *spi) {
|
|
(void) spi;
|
|
return HAL_GPIO_ReadPin(SPI_RDY_GPIO_Port, SPI_RDY_Pin);
|
|
}
|
|
|
|
static inline void hal_spi_select(SPI_TypeDef *spi, bool s) {
|
|
(void)spi;
|
|
HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, s);
|
|
}
|
|
|
|
static inline void hal_spi_done(SPI_TypeDef *spi) {
|
|
while((spi->SR & SPI_SR_TXC_Msk) == 0) spin(1);
|
|
spi->IFCR = 0xffff; // clear all flags
|
|
}
|
|
|
|
static bool hwspecific_is_ready(void) {
|
|
return hal_spi_ready(WIFISPI);
|
|
}
|
|
|
|
static void hwspecific_spi_begin(void *arg) {
|
|
hal_spi_select(WIFISPI, true);
|
|
(void) arg;
|
|
}
|
|
|
|
static void hwspecific_spi_txn(void *arg, uint8_t *txdata, uint8_t *rxdata, size_t len) {
|
|
while (len--) {
|
|
uint8_t rx = hal_spi_xfer_byte(WIFISPI, txdata != NULL ? *txdata++ : 0);
|
|
if (rxdata != NULL) *rxdata++ = rx;
|
|
}
|
|
hal_spi_done(WIFISPI);
|
|
(void) arg;
|
|
}
|
|
|
|
static void hwspecific_spi_end(void *arg) {
|
|
hal_spi_select(WIFISPI, false);
|
|
(void) arg;
|
|
}
|
|
|
|
void hwspecific_spi_init(void) {
|
|
HAL_GPIO_WritePin(SPI_CHIP_EN_GPIO_Port, SPI_CHIP_EN_Pin, 0);
|
|
hal_spi_init(WIFISPI, 128); // runs at 1.25MHz (SYS_CLK/128)
|
|
mg_delayms(10);
|
|
HAL_GPIO_WritePin(SPI_CHIP_EN_GPIO_Port, SPI_CHIP_EN_Pin, 1);
|
|
}
|
|
|
|
static const struct mg_tcpip_spi spi = {NULL, hwspecific_spi_begin, hwspecific_spi_end, hwspecific_spi_txn};
|
|
|
|
void wifi_setconfig(void *data) {
|
|
struct mg_tcpip_driver_st67w6_data *d = (struct mg_tcpip_driver_st67w6_data *) data;
|
|
d->wifi.ssid = WIFI_NAME;
|
|
d->wifi.pass = WIFI_PASS;
|
|
d->wifi.apssid = WIFI_AP_NAME;
|
|
d->wifi.appass = WIFI_AP_PASS;
|
|
d->wifi.apip = MG_IPV4(192, 168, 169, 1);
|
|
d->wifi.apmask = MG_IPV4(255, 255, 255, 0);
|
|
d->wifi.security = 0;
|
|
d->wifi.apsecurity = 0;
|
|
d->wifi.apchannel = 10;
|
|
d->wifi.apmode = ENABLE_WIFI_AP;
|
|
d->spi = (struct mg_tcpip_spi *) &spi;
|
|
d->is_ready = hwspecific_is_ready;
|
|
}
|