stm: Remove long-obsolete stm/ port.
This commit is contained in:
parent
63436ce22e
commit
aa7cf6f72f
@ -29,15 +29,13 @@ Major components in this repository:
|
||||
- py/ -- the core Python implementation, including compiler and runtime.
|
||||
- unix/ -- a version of Micro Python that runs on Unix.
|
||||
- stmhal/ -- a version of Micro Python that runs on the Micro Python board
|
||||
with an STM32F405RG (using ST's new Cube HAL drivers).
|
||||
with an STM32F405RG (using ST's Cube HAL drivers).
|
||||
- teensy/ -- a version of Micro Python that runs on the Teensy 3.1
|
||||
(preliminary but functional).
|
||||
|
||||
Additional components:
|
||||
- bare-arm/ -- a bare minimum version of Micro Python for ARM MCUs. Start
|
||||
with this if you want to port Micro Python to another microcontroller.
|
||||
- stm/ -- obsolete version of Micro Python for the Micro Python board
|
||||
that uses ST's old peripheral drivers.
|
||||
- unix-cpy/ -- a version of Micro Python that outputs bytecode (for testing).
|
||||
- tests/ -- test framework and test scripts.
|
||||
- tools/ -- various tools, including the pyboard.py module.
|
||||
|
1
stm/.gitignore
vendored
1
stm/.gitignore
vendored
@ -1 +0,0 @@
|
||||
build
|
220
stm/Makefile
220
stm/Makefile
@ -1,220 +0,0 @@
|
||||
include ../py/mkenv.mk
|
||||
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS = qstrdefsport.h
|
||||
|
||||
# include py core make definitions
|
||||
include ../py/py.mk
|
||||
|
||||
CMSIS_DIR=cmsis
|
||||
STMPERIPH_DIR=stmperiph
|
||||
STMUSB_DIR=stmusb
|
||||
STMUSBD_DIR=stmusbd
|
||||
STMUSBH_DIR=stmusbh
|
||||
FATFS_DIR=fatfs
|
||||
CC3K_DIR=cc3k
|
||||
DFU=../tools/dfu.py
|
||||
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
|
||||
INC = -I.
|
||||
INC += -I$(PY_SRC)
|
||||
INC += -I$(BUILD)
|
||||
INC += -I$(CMSIS_DIR)
|
||||
INC += -I$(STMPERIPH_DIR)
|
||||
INC += -I$(STMUSB_DIR)
|
||||
INC += -I$(STMUSBD_DIR)
|
||||
INC += -I$(STMUSBH_DIR)
|
||||
INC += -I$(FATFS_DIR)
|
||||
#INC += -I$(CC3K_DIR)
|
||||
|
||||
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
|
||||
CFLAGS = $(INC) -Wall -Werror -ansi -std=gnu99 $(CFLAGS_CORTEX_M4) $(COPT)
|
||||
|
||||
BOARD ?= PYBOARD4
|
||||
ifeq ($(wildcard boards/$(BOARD)/.),)
|
||||
$(error Invalid BOARD specified)
|
||||
endif
|
||||
CFLAGS += -Iboards/$(BOARD)
|
||||
|
||||
#Debugging/Optimization
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -g -DPENDSV_DEBUG
|
||||
COPT = -O0
|
||||
else
|
||||
COPT += -Os -DNDEBUG
|
||||
endif
|
||||
|
||||
LDFLAGS = --nostdlib -T stm32f405.ld -Map=$(@:.elf=.map) --cref
|
||||
LIBS =
|
||||
|
||||
# uncomment this if you want libgcc
|
||||
#LIBS += $(shell $(CC) -print-libgcc-file-name)
|
||||
|
||||
SRC_C = \
|
||||
main.c \
|
||||
printf.c \
|
||||
math.c \
|
||||
system_stm32f4xx.c \
|
||||
stm32fxxx_it.c \
|
||||
string0.c \
|
||||
malloc0.c \
|
||||
systick.c \
|
||||
pendsv.c \
|
||||
gccollect.c \
|
||||
lexerfatfs.c \
|
||||
import.c \
|
||||
pyexec.c \
|
||||
led.c \
|
||||
gpio.c \
|
||||
lcd.c \
|
||||
servo.c \
|
||||
flash.c \
|
||||
storage.c \
|
||||
accel.c \
|
||||
usart.c \
|
||||
usb.c \
|
||||
timer.c \
|
||||
audio.c \
|
||||
sdcard.c \
|
||||
i2c.c \
|
||||
adc.c \
|
||||
rtc.c \
|
||||
file.c \
|
||||
pin.c \
|
||||
pin_named_pins.c \
|
||||
pin_map.c \
|
||||
exti.c \
|
||||
usrsw.c \
|
||||
pybmodule.c \
|
||||
# pybwlan.c \
|
||||
|
||||
SRC_S = \
|
||||
startup_stm32f40xx.s \
|
||||
gchelper.s \
|
||||
|
||||
SRC_STMPERIPH = $(addprefix $(STMPERIPH_DIR)/,\
|
||||
stm_misc.c \
|
||||
stm32f4xx_rcc.c \
|
||||
stm32f4xx_syscfg.c \
|
||||
stm32f4xx_flash.c \
|
||||
stm32f4xx_dma.c \
|
||||
stm32f4xx_gpio.c \
|
||||
stm32f4xx_exti.c \
|
||||
stm32f4xx_tim.c \
|
||||
stm32f4xx_sdio.c \
|
||||
stm32f4xx_pwr.c \
|
||||
stm32f4xx_rtc.c \
|
||||
stm32f4xx_usart.c \
|
||||
stm32f4xx_spi.c \
|
||||
stm32f4xx_dac.c \
|
||||
stm32f4xx_rng.c \
|
||||
stm32f4xx_i2c.c \
|
||||
stm32f4xx_adc.c \
|
||||
stm324x7i_eval.c \
|
||||
stm324x7i_eval_sdio_sd.c \
|
||||
)
|
||||
|
||||
SRC_STMUSB = $(addprefix $(STMUSB_DIR)/,\
|
||||
usb_core.c \
|
||||
usb_bsp.c \
|
||||
usb_dcd.c \
|
||||
usb_dcd_int.c \
|
||||
usb_hcd.c \
|
||||
usb_hcd_int.c \
|
||||
)
|
||||
# usb_otg.c \
|
||||
|
||||
SRC_STMUSBD = $(addprefix $(STMUSBD_DIR)/,\
|
||||
usbd_core.c \
|
||||
usbd_ioreq.c \
|
||||
usbd_req.c \
|
||||
usbd_usr.c \
|
||||
usbd_desc.c \
|
||||
usbd_pyb_core.c \
|
||||
usbd_pyb_core2.c \
|
||||
usbd_cdc_vcp.c \
|
||||
usbd_msc_bot.c \
|
||||
usbd_msc_data.c \
|
||||
usbd_msc_scsi.c \
|
||||
usbd_storage_msd.c \
|
||||
)
|
||||
|
||||
SRC_STMUSBH = $(addprefix $(STMUSBH_DIR)/,\
|
||||
usbh_core.c \
|
||||
usbh_hcs.c \
|
||||
usbh_stdreq.c \
|
||||
usbh_ioreq.c \
|
||||
usbh_usr.c \
|
||||
usbh_hid_core.c \
|
||||
usbh_hid_mouse.c \
|
||||
usbh_hid_keybd.c \
|
||||
)
|
||||
|
||||
SRC_FATFS = $(addprefix $(FATFS_DIR)/,\
|
||||
ff.c \
|
||||
diskio.c \
|
||||
ccsbcs.c \
|
||||
)
|
||||
|
||||
SRC_CC3K = $(addprefix $(CC3K_DIR)/,\
|
||||
cc3000_common.c \
|
||||
evnt_handler.c \
|
||||
hci.c \
|
||||
netapp.c \
|
||||
nvmem.c \
|
||||
security.c \
|
||||
socket.c \
|
||||
wlan.c \
|
||||
ccspi.c \
|
||||
pybcc3k.c \
|
||||
)
|
||||
|
||||
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o) $(SRC_STMPERIPH:.c=.o) $(SRC_STMUSB:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_STMUSBD:.c=.o))
|
||||
#OBJ += $(addprefix $(BUILD)/, $(SRC_STMUSBH:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_FATFS:.c=.o))
|
||||
#OBJ += $(addprefix $(BUILD)/, $(SRC_CC3K:.c=.o))
|
||||
OBJ += $(BUILD)/pins_$(BOARD).o
|
||||
|
||||
all: $(BUILD)/flash.dfu
|
||||
|
||||
$(BUILD)/flash.dfu: $(BUILD)/flash0.bin $(BUILD)/flash1.bin
|
||||
$(ECHO) "Create $@"
|
||||
$(Q)$(PYTHON) $(DFU) -b 0x08000000:$(BUILD)/flash0.bin -b 0x08020000:$(BUILD)/flash1.bin $@
|
||||
|
||||
$(BUILD)/flash0.bin: $(BUILD)/flash.elf
|
||||
$(Q)$(OBJCOPY) -O binary -j .isr_vector $^ $@
|
||||
|
||||
$(BUILD)/flash1.bin: $(BUILD)/flash.elf
|
||||
$(Q)$(OBJCOPY) -O binary -j .text -j .data $^ $@
|
||||
|
||||
$(BUILD)/flash.elf: $(OBJ)
|
||||
$(ECHO) "LINK $@"
|
||||
$(Q)$(LD) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
|
||||
$(Q)$(SIZE) $@
|
||||
|
||||
MAKE_PINS = boards/make-pins.py
|
||||
BOARD_PINS = boards/$(BOARD)/pins.csv
|
||||
AF_FILE = boards/stm32f4xx-af.csv
|
||||
PREFIX_FILE = boards/stm32f4xx-prefix.c
|
||||
GEN_PINS_SRC = $(BUILD)/pins_$(BOARD).c
|
||||
GEN_PINS_HDR = $(BUILD)/pins.h
|
||||
|
||||
# Making OBJ use an order-only depenedency on the generated pins.h file
|
||||
# has the side effect of making the pins.h file before we actually compile
|
||||
# any of the objects. The normal dependency generation will deal with the
|
||||
# case when pins.h is modified. But when it doesn't exist, we don't know
|
||||
# which source files might need it.
|
||||
$(OBJ): | $(BUILD)/pins.h
|
||||
|
||||
# Use a pattern rule here so that make will only call make-pins.py once to make
|
||||
# both pins_$(BOARD).c and pins.h
|
||||
$(BUILD)/%_$(BOARD).c $(BUILD)/%.h: boards/$(BOARD)/%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE)
|
||||
$(ECHO) "Create $@"
|
||||
$(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) > $(GEN_PINS_SRC)
|
||||
|
||||
$(BUILD)/pins_$(BOARD).o: $(BUILD)/pins_$(BOARD).c
|
||||
$(call compile_c)
|
||||
|
||||
include ../py/mkrules.mk
|
300
stm/accel.c
300
stm/accel.c
@ -1,300 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_rcc.h>
|
||||
#include <stm32f4xx_gpio.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "systick.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "accel.h"
|
||||
|
||||
#define ACCEL_ADDR (0x4c)
|
||||
|
||||
void accel_init(void) {
|
||||
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // enable I2C1
|
||||
|
||||
//gpio_pin_init(GPIOB, 6 /* B6 is SCL */, 2 /* AF mode */, 1 /* open drain output */, 1 /* 25 MHz */, 0 /* no pull up or pull down */);
|
||||
//gpio_pin_init(GPIOB, 7 /* B7 is SDA */, 2 /* AF mode */, 1 /* open drain output */, 1 /* 25 MHz */, 0 /* no pull up or pull down */);
|
||||
//gpio_pin_af(GPIOB, 6, 4 /* AF 4 for I2C1 */);
|
||||
//gpio_pin_af(GPIOB, 7, 4 /* AF 4 for I2C1 */);
|
||||
// XXX untested GPIO init! (was above code)
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
// PB5 is connected to AVDD; pull high to enable MMA accel device
|
||||
GPIOB->BSRRH = GPIO_Pin_5; // PB5 low to start with
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
// PB6=SCL, PB7=SDA
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
// alternate functions for SCL and SDA
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
|
||||
|
||||
// get clock speeds
|
||||
RCC_ClocksTypeDef rcc_clocks;
|
||||
RCC_GetClocksFreq(&rcc_clocks);
|
||||
|
||||
// disable the I2C peripheral before we configure it
|
||||
I2C1->CR1 &= ~I2C_CR1_PE;
|
||||
|
||||
// program peripheral input clock
|
||||
I2C1->CR2 = 4; // no interrupts; 4 MHz (hopefully!) (could go up to 42MHz)
|
||||
|
||||
// configure clock control reg
|
||||
uint32_t freq = rcc_clocks.PCLK1_Frequency / (100000 << 1); // want 100kHz, this is the formula for freq
|
||||
I2C1->CCR = freq; // standard mode (speed), freq calculated as above
|
||||
|
||||
// configure rise time reg
|
||||
I2C1->TRISE = (rcc_clocks.PCLK1_Frequency / 1000000) + 1; // formula for trise, gives maximum rise time
|
||||
|
||||
// enable the I2C peripheral
|
||||
I2C1->CR1 |= I2C_CR1_PE;
|
||||
|
||||
// wait 20ms, then turn on AVDD, then wait 20ms again; this seems to work, but maybe can decrease delays
|
||||
// doesn't work for soft reboot; 50ms doesn't work either...
|
||||
sys_tick_delay_ms(20);
|
||||
GPIOB->BSRRL = GPIO_Pin_5;
|
||||
sys_tick_delay_ms(20);
|
||||
|
||||
// set START bit in CR1 to generate a start cond!
|
||||
|
||||
// init the chip via I2C commands
|
||||
accel_start(ACCEL_ADDR, 1);
|
||||
accel_send_byte(0);
|
||||
accel_stop();
|
||||
|
||||
/*
|
||||
// read and print all 11 registers
|
||||
accel_start(ACCEL_ADDR, 1);
|
||||
accel_send_byte(0);
|
||||
accel_restart(ACCEL_ADDR, 0);
|
||||
for (int i = 0; i <= 0xa; i++) {
|
||||
int data;
|
||||
if (i == 0xa) {
|
||||
data = accel_read_nack();
|
||||
} else {
|
||||
data = accel_read_ack();
|
||||
}
|
||||
printf(" %02x", data);
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
// put into active mode
|
||||
accel_start(ACCEL_ADDR, 1);
|
||||
accel_send_byte(7); // mode
|
||||
accel_send_byte(1); // active mode
|
||||
accel_stop();
|
||||
|
||||
/*
|
||||
// infinite loop to read values
|
||||
for (;;) {
|
||||
sys_tick_delay_ms(500);
|
||||
|
||||
accel_start(ACCEL_ADDR, 1);
|
||||
accel_send_byte(0);
|
||||
accel_restart(ACCEL_ADDR, 0);
|
||||
for (int i = 0; i <= 3; i++) {
|
||||
int data;
|
||||
if (i == 3) {
|
||||
data = accel_read_nack();
|
||||
printf(" %02x\n", data);
|
||||
} else {
|
||||
data = accel_read_ack() & 0x3f;
|
||||
if (data & 0x20) {
|
||||
data |= ~0x1f;
|
||||
}
|
||||
printf(" % 2d", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
static uint32_t i2c_get_sr(void) {
|
||||
// must read SR1 first, then SR2, as the read can clear some flags
|
||||
uint32_t sr1 = I2C1->SR1;
|
||||
uint32_t sr2 = I2C1->SR2;
|
||||
return (sr2 << 16) | sr1;
|
||||
}
|
||||
|
||||
void accel_restart(uint8_t addr, int write) {
|
||||
// send start condition
|
||||
I2C1->CR1 |= I2C_CR1_START;
|
||||
|
||||
// wait for BUSY, MSL and SB --> Slave has acknowledged start condition
|
||||
uint32_t timeout = 1000000;
|
||||
while ((i2c_get_sr() & 0x00030001) != 0x00030001) {
|
||||
if (--timeout == 0) {
|
||||
printf("timeout in accel_restart\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (write) {
|
||||
// send address and write bit
|
||||
I2C1->DR = (addr << 1) | 0;
|
||||
// wait for BUSY, MSL, ADDR, TXE and TRA
|
||||
timeout = 1000000;
|
||||
while ((i2c_get_sr() & 0x00070082) != 0x00070082) {
|
||||
if (--timeout == 0) {
|
||||
printf("timeout in accel_restart write\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// send address and read bit
|
||||
I2C1->DR = (addr << 1) | 1;
|
||||
// wait for BUSY, MSL and ADDR flags
|
||||
timeout = 1000000;
|
||||
while ((i2c_get_sr() & 0x00030002) != 0x00030002) {
|
||||
if (--timeout == 0) {
|
||||
printf("timeout in accel_restart read\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void accel_start(uint8_t addr, int write) {
|
||||
// wait until I2C is not busy
|
||||
uint32_t timeout = 1000000;
|
||||
while (I2C1->SR2 & I2C_SR2_BUSY) {
|
||||
if (--timeout == 0) {
|
||||
printf("timeout in accel_start\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// do rest of start
|
||||
accel_restart(addr, write);
|
||||
}
|
||||
|
||||
void accel_send_byte(uint8_t data) {
|
||||
// send byte
|
||||
I2C1->DR = data;
|
||||
// wait for TRA, BUSY, MSL, TXE and BTF (byte transmitted)
|
||||
uint32_t timeout = 1000000;
|
||||
while ((i2c_get_sr() & 0x00070084) != 0x00070084) {
|
||||
if (--timeout == 0) {
|
||||
printf("timeout in accel_send_byte\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t accel_read_ack(void) {
|
||||
// enable ACK of received byte
|
||||
I2C1->CR1 |= I2C_CR1_ACK;
|
||||
// wait for BUSY, MSL and RXNE (byte received)
|
||||
uint32_t timeout = 1000000;
|
||||
while ((i2c_get_sr() & 0x00030040) != 0x00030040) {
|
||||
if (--timeout == 0) {
|
||||
printf("timeout in accel_read_ack\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// read and return data
|
||||
uint8_t data = I2C1->DR;
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t accel_read_nack(void) {
|
||||
// disable ACK of received byte (to indicate end of receiving)
|
||||
I2C1->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ACK);
|
||||
// last byte should apparently also generate a stop condition
|
||||
I2C1->CR1 |= I2C_CR1_STOP;
|
||||
// wait for BUSY, MSL and RXNE (byte received)
|
||||
uint32_t timeout = 1000000;
|
||||
while ((i2c_get_sr() & 0x00030040) != 0x00030040) {
|
||||
if (--timeout == 0) {
|
||||
printf("timeout in accel_read_nack\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// read and return data
|
||||
uint8_t data = I2C1->DR;
|
||||
return data;
|
||||
}
|
||||
|
||||
void accel_stop(void) {
|
||||
// send stop condition
|
||||
I2C1->CR1 |= I2C_CR1_STOP;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
|
||||
int accel_buf[12];
|
||||
|
||||
mp_obj_t pyb_accel_read(void) {
|
||||
for (int i = 0; i <= 6; i += 3) {
|
||||
accel_buf[0 + i] = accel_buf[0 + i + 3];
|
||||
accel_buf[1 + i] = accel_buf[1 + i + 3];
|
||||
accel_buf[2 + i] = accel_buf[2 + i + 3];
|
||||
}
|
||||
|
||||
accel_start(ACCEL_ADDR, 1);
|
||||
accel_send_byte(0);
|
||||
accel_restart(ACCEL_ADDR, 0);
|
||||
for (int i = 0; i <= 2; i++) {
|
||||
int v = accel_read_ack() & 0x3f;
|
||||
if (v & 0x20) {
|
||||
v |= ~0x1f;
|
||||
}
|
||||
accel_buf[9 + i] = v;
|
||||
}
|
||||
int jolt_info = accel_read_nack();
|
||||
|
||||
mp_obj_t data[4];
|
||||
data[0] = mp_obj_new_int(accel_buf[0] + accel_buf[3] + accel_buf[6] + accel_buf[9]);
|
||||
data[1] = mp_obj_new_int(accel_buf[1] + accel_buf[4] + accel_buf[7] + accel_buf[10]);
|
||||
data[2] = mp_obj_new_int(accel_buf[2] + accel_buf[5] + accel_buf[8] + accel_buf[11]);
|
||||
data[3] = mp_obj_new_int(jolt_info);
|
||||
|
||||
return mp_obj_new_tuple(4, data);
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_accel_read_obj, pyb_accel_read);
|
||||
|
||||
mp_obj_t pyb_accel_read_all(void) {
|
||||
mp_obj_t data[11];
|
||||
accel_start(ACCEL_ADDR, 1);
|
||||
accel_send_byte(0);
|
||||
accel_restart(ACCEL_ADDR, 0);
|
||||
for (int i = 0; i <= 9; i++) {
|
||||
data[i] = mp_obj_new_int(accel_read_ack());
|
||||
}
|
||||
data[10] = mp_obj_new_int(accel_read_nack());
|
||||
|
||||
return mp_obj_new_tuple(11, data);
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_accel_read_all_obj, pyb_accel_read_all);
|
||||
|
||||
mp_obj_t pyb_accel_write_mode(mp_obj_t o_int, mp_obj_t o_mode) {
|
||||
accel_start(ACCEL_ADDR, 1);
|
||||
accel_send_byte(6); // start at int
|
||||
accel_send_byte(mp_obj_get_int(o_int));
|
||||
accel_send_byte(mp_obj_get_int(o_mode));
|
||||
accel_stop();
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(pyb_accel_write_mode_obj, pyb_accel_write_mode);
|
11
stm/accel.h
11
stm/accel.h
@ -1,11 +0,0 @@
|
||||
void accel_init(void);
|
||||
void accel_restart(uint8_t addr, int write);
|
||||
void accel_start(uint8_t addr, int write);
|
||||
void accel_send_byte(uint8_t data);
|
||||
uint8_t accel_read_ack(void);
|
||||
uint8_t accel_read_nack(void);
|
||||
void accel_stop(void);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_accel_read_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_accel_read_all_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_accel_write_mode_obj);
|
446
stm/adc.c
446
stm/adc.c
@ -1,446 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stm32f4xx.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "nlr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "adc.h"
|
||||
|
||||
/* ADC defintions */
|
||||
#define ADCx (ADC1)
|
||||
#define ADCx_CLK (RCC_APB2Periph_ADC1)
|
||||
#define ADC_NUM_CHANNELS (16)
|
||||
|
||||
/* Internally connected ADC channels Temp/VBAT/VREF*/
|
||||
#if defined (STM32F40XX) || defined(STM32F41XX) || defined(STM32F40_41xxx)
|
||||
#define ADC_TEMP_CHANNEL (16)
|
||||
#define ADC_VBAT_CHANNEL (18)
|
||||
#define ADC_VREF_CHANNEL (17)
|
||||
#elif defined (STM32F42XX) || defined(STM32F43XX)
|
||||
#define ADC_TEMP_CHANNEL (18)
|
||||
#define ADC_VBAT_CHANNEL (18) /* same channel as TEMP */
|
||||
#define ADC_VREF_CHANNEL (17)
|
||||
#endif
|
||||
|
||||
/* Core temperature sensor definitions */
|
||||
#define CORE_TEMP_V25 (943) /* (0.76v/3.3v)*(2^ADC resoultion) */
|
||||
#define CORE_TEMP_AVG_SLOPE (3) /* (2.5mv/3.3v)*(2^ADC resoultion) */
|
||||
|
||||
/* VBAT divider */
|
||||
#if defined (STM32F40XX) || defined(STM32F41XX) || defined(STM32F40_41xxx)
|
||||
#define VBAT_DIV (2)
|
||||
#elif defined (STM32F42XX) || defined(STM32F43XX)
|
||||
#define VBAT_DIV (4)
|
||||
#endif
|
||||
|
||||
/* GPIO struct */
|
||||
typedef struct {
|
||||
GPIO_TypeDef* port;
|
||||
uint32_t pin;
|
||||
} gpio_t;
|
||||
|
||||
/* ADC GPIOs */
|
||||
static const gpio_t adc_gpio[] = {
|
||||
{GPIOA, GPIO_Pin_0}, /* ADC123_IN0 */
|
||||
{GPIOA, GPIO_Pin_1}, /* ADC123_IN1 */
|
||||
{GPIOA, GPIO_Pin_2}, /* ADC123_IN2 */
|
||||
{GPIOA, GPIO_Pin_3}, /* ADC123_IN3 */
|
||||
{GPIOA, GPIO_Pin_4}, /* ADC12_IN4 */
|
||||
{GPIOA, GPIO_Pin_5}, /* ADC12_IN5 */
|
||||
{GPIOA, GPIO_Pin_6}, /* ADC12_IN6 */
|
||||
{GPIOA, GPIO_Pin_7}, /* ADC12_IN7 */
|
||||
{GPIOB, GPIO_Pin_0}, /* ADC12_IN8 */
|
||||
{GPIOB, GPIO_Pin_1}, /* ADC12_IN9 */
|
||||
{GPIOC, GPIO_Pin_0}, /* ADC123_IN10 */
|
||||
{GPIOC, GPIO_Pin_1}, /* ADC123_IN11 */
|
||||
{GPIOC, GPIO_Pin_2}, /* ADC123_IN12 */
|
||||
{GPIOC, GPIO_Pin_3}, /* ADC123_IN13 */
|
||||
{GPIOC, GPIO_Pin_4}, /* ADC12_IN14 */
|
||||
{GPIOC, GPIO_Pin_5}, /* ADC12_IN15 */
|
||||
|
||||
};
|
||||
|
||||
void adc_init_all(uint32_t resolution) {
|
||||
ADC_InitTypeDef ADC_InitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
ADC_CommonInitTypeDef ADC_CommonInitStructure;
|
||||
|
||||
/* Enable ADCx, DMA and GPIO clocks */
|
||||
#if 0
|
||||
/* GPIO clocks enabled in main */
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |
|
||||
RCC_AHB1Periph_GPIOB |
|
||||
RCC_AHB1Periph_GPIOC, ENABLE);
|
||||
#endif
|
||||
RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);
|
||||
|
||||
/* ADC Common Init */
|
||||
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
|
||||
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
|
||||
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
|
||||
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
|
||||
ADC_CommonInit(&ADC_CommonInitStructure);
|
||||
|
||||
/* Configure ADC GPIOs */
|
||||
for (int i=0; i<ADC_NUM_CHANNELS; i++) {
|
||||
GPIO_InitStructure.GPIO_Pin = adc_gpio[i].pin;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(adc_gpio[i].port, &GPIO_InitStructure);
|
||||
}
|
||||
|
||||
/* ADCx Init */
|
||||
// ADC_DeInit();
|
||||
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
|
||||
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
|
||||
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
|
||||
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
|
||||
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
|
||||
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
|
||||
ADC_InitStructure.ADC_NbrOfConversion = 1;
|
||||
ADC_Init(ADCx, &ADC_InitStructure);
|
||||
|
||||
/* Enable ADCx */
|
||||
ADC_Cmd(ADCx, ENABLE);
|
||||
|
||||
/* Enable VBAT/VREF monitor */
|
||||
ADC_VBATCmd(ENABLE);
|
||||
|
||||
/* Enable temperature sensor */
|
||||
ADC_TempSensorVrefintCmd(ENABLE);
|
||||
}
|
||||
|
||||
void adc_init_single(uint32_t channel) {
|
||||
ADC_InitTypeDef ADC_InitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
ADC_CommonInitTypeDef ADC_CommonInitStructure;
|
||||
|
||||
/* Enable ADCx, DMA and GPIO clocks */
|
||||
#if 0
|
||||
/* GPIO clocks enabled in main */
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |
|
||||
RCC_AHB1Periph_GPIOB |
|
||||
RCC_AHB1Periph_GPIOC, ENABLE);
|
||||
#endif
|
||||
RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);
|
||||
|
||||
/* ADC Common Init */
|
||||
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
|
||||
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
|
||||
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
|
||||
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
|
||||
ADC_CommonInit(&ADC_CommonInitStructure);
|
||||
|
||||
/* Configure ADC GPIO for the single channel */
|
||||
GPIO_InitStructure.GPIO_Pin = adc_gpio[channel].pin;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(adc_gpio[channel].port, &GPIO_InitStructure);
|
||||
|
||||
/* ADCx Init */
|
||||
// ADC_DeInit();
|
||||
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
|
||||
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
|
||||
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
|
||||
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
|
||||
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
|
||||
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
|
||||
ADC_InitStructure.ADC_NbrOfConversion = 1;
|
||||
ADC_Init(ADCx, &ADC_InitStructure);
|
||||
|
||||
/* Enable ADCx */
|
||||
ADC_Cmd(ADCx, ENABLE);
|
||||
|
||||
/* Enable VBAT/VREF monitor */
|
||||
ADC_VBATCmd(ENABLE);
|
||||
|
||||
/* Enable temperature sensor */
|
||||
ADC_TempSensorVrefintCmd(ENABLE);
|
||||
}
|
||||
|
||||
uint32_t adc_read_channel(int channel)
|
||||
{
|
||||
int timeout = 10000;
|
||||
|
||||
if (channel > (ADC_NUM_CHANNELS-1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ADC regular channel config ADC/Channel/SEQ Rank/Sample time */
|
||||
ADC_RegularChannelConfig(ADCx, channel, 1, ADC_SampleTime_15Cycles);
|
||||
|
||||
/* Start ADC single conversion */
|
||||
ADC_SoftwareStartConv(ADCx);
|
||||
|
||||
/* Wait for conversion to be complete*/
|
||||
while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) && --timeout >0) {
|
||||
}
|
||||
|
||||
/* ADC conversion timed out */
|
||||
if (timeout == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return converted data */
|
||||
return ADC_GetConversionValue(ADCx);
|
||||
}
|
||||
|
||||
int adc_read_core_temp()
|
||||
{
|
||||
int timeout = 10000;
|
||||
|
||||
/* ADC temperature sensor channel config ADC/Channel/SEQ Rank/Sample time */
|
||||
/* Note: sample time must be higher than minimum sample time */
|
||||
ADC_RegularChannelConfig(ADCx, ADC_TEMP_CHANNEL, 1, ADC_SampleTime_480Cycles);
|
||||
|
||||
/* Start ADC single conversion */
|
||||
ADC_SoftwareStartConv(ADCx);
|
||||
|
||||
/* Wait for conversion to be complete*/
|
||||
while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) && --timeout >0) {
|
||||
}
|
||||
|
||||
/* ADC conversion timed out */
|
||||
if (timeout == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Convert ADC reading to temperature */
|
||||
/* Temperature formula from datasheet P.411 */
|
||||
return ((ADC_GetConversionValue(ADCx) - CORE_TEMP_V25) / CORE_TEMP_AVG_SLOPE) + 25;
|
||||
}
|
||||
|
||||
float adc_read_core_vbat()
|
||||
{
|
||||
int timeout = 10000;
|
||||
|
||||
/* ADC VBAT channel config ADC/Channel/SEQ Rank/Sample time */
|
||||
/* Note: sample time must be higher than minimum sample time */
|
||||
ADC_RegularChannelConfig(ADCx, ADC_VBAT_CHANNEL, 1, ADC_SampleTime_144Cycles);
|
||||
|
||||
/* Start ADC single conversion */
|
||||
ADC_SoftwareStartConv(ADCx);
|
||||
|
||||
/* Wait for conversion to be complete */
|
||||
while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) && --timeout >0) {
|
||||
}
|
||||
|
||||
/* ADC conversion timed out */
|
||||
if (timeout == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Convert ADC reading to voltage, VBAT pin is
|
||||
internally connected to a bridge divider by VBAT_DIV */
|
||||
return ADC_GetConversionValue(ADCx)*VBAT_DIV/4096.0f*3.3f;
|
||||
}
|
||||
|
||||
float adc_read_core_vref()
|
||||
{
|
||||
int timeout = 10000;
|
||||
|
||||
/* ADC VBAT channel config ADC/Channel/SEQ Rank/Sample time */
|
||||
/* Note: sample time must be higher than minimum sample time */
|
||||
ADC_RegularChannelConfig(ADCx, ADC_VREF_CHANNEL, 1, ADC_SampleTime_112Cycles);
|
||||
|
||||
/* Start ADC single conversion */
|
||||
ADC_SoftwareStartConv(ADCx);
|
||||
|
||||
/* Wait for conversion to be complete*/
|
||||
while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) && --timeout >0) {
|
||||
}
|
||||
|
||||
/* ADC conversion timed out */
|
||||
if (timeout == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Convert ADC reading to voltage */
|
||||
return ADC_GetConversionValue(ADCx)/4096.0f*3.3f;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings : adc_all object */
|
||||
|
||||
typedef struct _pyb_obj_adc_all_t {
|
||||
mp_obj_base_t base;
|
||||
bool is_enabled;
|
||||
} pyb_obj_adc_all_t;
|
||||
|
||||
static void adc_all_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
print(env, "<ADC all>");
|
||||
}
|
||||
|
||||
static mp_obj_t adc_all_read_channel(mp_obj_t self_in, mp_obj_t channel) {
|
||||
pyb_obj_adc_all_t *self = self_in;
|
||||
|
||||
if (self->is_enabled) {
|
||||
uint32_t chan = mp_obj_get_int(channel);
|
||||
uint32_t data = adc_read_channel(chan);
|
||||
return mp_obj_new_int(data);
|
||||
} else {
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
static mp_obj_t adc_all_read_core_temp(mp_obj_t self_in) {
|
||||
pyb_obj_adc_all_t *self = self_in;
|
||||
|
||||
if (self->is_enabled) {
|
||||
int data = adc_read_core_temp();
|
||||
return mp_obj_new_int(data);
|
||||
} else {
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
static mp_obj_t adc_all_read_core_vbat(mp_obj_t self_in) {
|
||||
pyb_obj_adc_all_t *self = self_in;
|
||||
|
||||
if (self->is_enabled) {
|
||||
float data = adc_read_core_vbat();
|
||||
return mp_obj_new_float(data);
|
||||
} else {
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
static mp_obj_t adc_all_read_core_vref(mp_obj_t self_in) {
|
||||
pyb_obj_adc_all_t *self = self_in;
|
||||
|
||||
if (self->is_enabled) {
|
||||
float data = adc_read_core_vref();
|
||||
return mp_obj_new_float(data);
|
||||
} else {
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(adc_all_read_channel_obj, adc_all_read_channel);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_temp_obj, adc_all_read_core_temp);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_vbat_obj, adc_all_read_core_vbat);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_vref_obj, adc_all_read_core_vref);
|
||||
|
||||
STATIC const mp_map_elem_t adc_all_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read_channel), (mp_obj_t) &adc_all_read_channel_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read_core_temp), (mp_obj_t)&adc_all_read_core_temp_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read_core_vbat), (mp_obj_t)&adc_all_read_core_vbat_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read_core_vref), (mp_obj_t)&adc_all_read_core_vref_obj},
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(adc_all_locals_dict, adc_all_locals_dict_table);
|
||||
|
||||
static const mp_obj_type_t adc_all_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_ADC,
|
||||
.print = adc_all_print,
|
||||
.locals_dict = (mp_obj_t)&adc_all_locals_dict,
|
||||
};
|
||||
|
||||
mp_obj_t pyb_ADC_all(mp_obj_t resolution) {
|
||||
/* init ADC */
|
||||
adc_init_all(mp_obj_get_int(resolution));
|
||||
|
||||
pyb_obj_adc_all_t *o = m_new_obj(pyb_obj_adc_all_t);
|
||||
o->base.type = &adc_all_type;
|
||||
o->is_enabled = true;
|
||||
return o;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(pyb_ADC_all_obj, pyb_ADC_all);
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings : adc object (single channel) */
|
||||
|
||||
typedef struct _pyb_obj_adc_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t pin_name;
|
||||
int channel;
|
||||
bool is_enabled;
|
||||
} pyb_obj_adc_t;
|
||||
|
||||
static void adc_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_obj_adc_t *self = self_in;
|
||||
print(env, "<ADC on ");
|
||||
mp_obj_print_helper(print, env, self->pin_name, PRINT_STR);
|
||||
print(env, " channel=%lu>", self->channel);
|
||||
}
|
||||
|
||||
static mp_obj_t adc_read(mp_obj_t self_in) {
|
||||
pyb_obj_adc_t *self = self_in;
|
||||
|
||||
if (self->is_enabled) {
|
||||
uint32_t data = adc_read_channel(self->channel);
|
||||
return mp_obj_new_int(data);
|
||||
} else {
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read);
|
||||
|
||||
STATIC const mp_map_elem_t adc_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&adc_read_obj},
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table);
|
||||
|
||||
static const mp_obj_type_t adc_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_ADC,
|
||||
.print = adc_print,
|
||||
.locals_dict = (mp_obj_t)&adc_locals_dict,
|
||||
};
|
||||
|
||||
mp_obj_t pyb_ADC(mp_obj_t pin_name_obj) {
|
||||
|
||||
pyb_obj_adc_t *o = m_new_obj(pyb_obj_adc_t);
|
||||
o->base.type = &adc_type;
|
||||
o->pin_name = pin_name_obj;
|
||||
|
||||
// work out the channel from the pin name
|
||||
const char *pin_name = mp_obj_str_get_str(pin_name_obj);
|
||||
GPIO_TypeDef *port;
|
||||
switch (pin_name[0]) {
|
||||
case 'A': case 'a': port = GPIOA; break;
|
||||
case 'B': case 'b': port = GPIOB; break;
|
||||
case 'C': case 'c': port = GPIOC; break;
|
||||
default: goto pin_error;
|
||||
}
|
||||
uint pin_num = 0;
|
||||
for (const char *s = pin_name + 1; *s; s++) {
|
||||
if (!('0' <= *s && *s <= '9')) {
|
||||
goto pin_error;
|
||||
}
|
||||
pin_num = 10 * pin_num + *s - '0';
|
||||
}
|
||||
if (!(0 <= pin_num && pin_num <= 15)) {
|
||||
goto pin_error;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < ADC_NUM_CHANNELS; i++) {
|
||||
if (adc_gpio[i].port == port && adc_gpio[i].pin == (1 << pin_num)) {
|
||||
o->channel = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == ADC_NUM_CHANNELS) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %s does not have ADC capabilities", pin_name));
|
||||
}
|
||||
|
||||
// init ADC just for this channel
|
||||
adc_init_single(o->channel);
|
||||
|
||||
o->is_enabled = true;
|
||||
|
||||
return o;
|
||||
|
||||
pin_error:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %s does not exist", pin_name));
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(pyb_ADC_obj, pyb_ADC);
|
@ -1,2 +0,0 @@
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_ADC_all_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_ADC_obj);
|
256
stm/audio.c
256
stm/audio.c
@ -1,256 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "stm32f4xx_dac.h"
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
#include "audio.h"
|
||||
|
||||
STATIC void TIM7_Config(uint freq) {
|
||||
// TIM7 clock enable
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);
|
||||
|
||||
// reset TIM7
|
||||
TIM_DeInit(TIM7);
|
||||
|
||||
// Compute the prescaler value so TIM7 triggers at freq-Hz
|
||||
uint16_t period = (uint16_t) ((SystemCoreClock / 2) / freq) - 1;
|
||||
|
||||
// Time base configuration
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
TIM_TimeBaseStructure.TIM_Period = period; // timer triggers with this period
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = 0; // timer runs at SystemCoreClock / 2
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // unused for TIM7
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // unused for TIM7
|
||||
TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure);
|
||||
|
||||
// TIM7 TRGO selection
|
||||
TIM_SelectOutputTrigger(TIM7, TIM_TRGOSource_Update);
|
||||
|
||||
// TIM7 enable counter
|
||||
TIM_Cmd(TIM7, ENABLE);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
typedef struct _pyb_audio_t {
|
||||
mp_obj_base_t base;
|
||||
uint dac_channel; // DAC_Channel_1 or DAC_Channel_2
|
||||
DMA_Stream_TypeDef *dma_stream; // DMA1_Stream6 or DMA1_Stream7
|
||||
} pyb_audio_t;
|
||||
|
||||
mp_obj_t pyb_audio_noise(mp_obj_t self_in, mp_obj_t freq) {
|
||||
pyb_audio_t *self = self_in;
|
||||
|
||||
// set TIM7 to trigger the DAC at the given frequency
|
||||
TIM7_Config(mp_obj_get_int(freq));
|
||||
|
||||
DAC_Cmd(self->dac_channel, DISABLE);
|
||||
|
||||
DAC_InitTypeDef DAC_InitStructure;
|
||||
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T7_TRGO;
|
||||
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_Noise;
|
||||
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bits10_0;
|
||||
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
|
||||
DAC_Init(self->dac_channel, &DAC_InitStructure);
|
||||
|
||||
DAC_Cmd(self->dac_channel, ENABLE);
|
||||
|
||||
if (self->dac_channel == DAC_Channel_1) {
|
||||
DAC_SetChannel1Data(DAC_Align_12b_L, 0x7ff0);
|
||||
} else {
|
||||
DAC_SetChannel2Data(DAC_Align_12b_L, 0x7ff0);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t pyb_audio_triangle(mp_obj_t self_in, mp_obj_t freq) {
|
||||
pyb_audio_t *self = self_in;
|
||||
|
||||
// set TIM7 to trigger the DAC at the given frequency
|
||||
TIM7_Config(mp_obj_get_int(freq));
|
||||
|
||||
DAC_Cmd(self->dac_channel, DISABLE);
|
||||
|
||||
DAC_InitTypeDef DAC_InitStructure;
|
||||
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T7_TRGO;
|
||||
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_Triangle;
|
||||
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1023;
|
||||
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
|
||||
DAC_Init(self->dac_channel, &DAC_InitStructure);
|
||||
|
||||
DAC_Cmd(self->dac_channel, ENABLE);
|
||||
|
||||
// set base value of triangle wave
|
||||
if (self->dac_channel == DAC_Channel_1) {
|
||||
DAC_SetChannel1Data(DAC_Align_12b_R, 0x100);
|
||||
} else {
|
||||
DAC_SetChannel2Data(DAC_Align_12b_R, 0x100);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
// direct access to DAC
|
||||
mp_obj_t pyb_audio_dac(mp_obj_t self_in, mp_obj_t val) {
|
||||
pyb_audio_t *self = self_in;
|
||||
if (self->dac_channel == DAC_Channel_1) {
|
||||
DAC_SetChannel1Data(DAC_Align_8b_R, mp_obj_get_int(val));
|
||||
} else {
|
||||
DAC_SetChannel2Data(DAC_Align_8b_R, mp_obj_get_int(val));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
#define DAC_DHR8R1_ADDRESS (DAC_BASE + 0x10)
|
||||
#define DAC_DHR8R2_ADDRESS (DAC_BASE + 0x1c)
|
||||
|
||||
// initiates a burst of RAM->DAC using DMA
|
||||
// input data is treated as an array of bytes (8 bit data)
|
||||
// TIM7 is used to set the frequency of the transfer
|
||||
mp_obj_t pyb_audio_dma(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
pyb_audio_t *self = args[0];
|
||||
|
||||
// set TIM7 to trigger the DAC at the given frequency
|
||||
TIM7_Config(mp_obj_get_int(args[2]));
|
||||
|
||||
mp_obj_type_t *type = mp_obj_get_type(args[1]);
|
||||
if (type->buffer_p.get_buffer == NULL) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "buffer argument must support buffer protocol"));
|
||||
}
|
||||
mp_buffer_info_t bufinfo;
|
||||
type->buffer_p.get_buffer(args[1], &bufinfo, MP_BUFFER_READ);
|
||||
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
|
||||
|
||||
DMA_Cmd(self->dma_stream, DISABLE);
|
||||
while (DMA_GetCmdStatus(self->dma_stream) != DISABLE) {
|
||||
}
|
||||
|
||||
DAC_Cmd(self->dac_channel, DISABLE);
|
||||
|
||||
// DAC channel configuration
|
||||
DAC_InitTypeDef DAC_InitStructure;
|
||||
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T7_TRGO;
|
||||
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
|
||||
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1; // unused, but need to set it to a valid value
|
||||
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
|
||||
DAC_Init(self->dac_channel, &DAC_InitStructure);
|
||||
|
||||
// DMA1_Stream[67] channel7 configuration
|
||||
DMA_DeInit(self->dma_stream);
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
DMA_InitStructure.DMA_Channel = DMA_Channel_7;
|
||||
if (self->dac_channel == DAC_Channel_1) {
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR8R1_ADDRESS;
|
||||
} else {
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR8R2_ADDRESS;
|
||||
}
|
||||
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)bufinfo.buf;
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
|
||||
DMA_InitStructure.DMA_BufferSize = bufinfo.len;
|
||||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||||
mp_map_elem_t *kw_mode = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("mode")), MP_MAP_LOOKUP);
|
||||
DMA_InitStructure.DMA_Mode = kw_mode == NULL ? DMA_Mode_Normal : mp_obj_get_int(kw_mode->value); // normal = 0, circular = 0x100
|
||||
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
||||
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
|
||||
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
|
||||
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
|
||||
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
||||
DMA_Init(self->dma_stream, &DMA_InitStructure);
|
||||
|
||||
// enable DMA stream
|
||||
DMA_Cmd(self->dma_stream, ENABLE);
|
||||
while (DMA_GetCmdStatus(self->dma_stream) == DISABLE) {
|
||||
}
|
||||
|
||||
// enable DAC channel
|
||||
DAC_Cmd(self->dac_channel, ENABLE);
|
||||
|
||||
// enable DMA for DAC channel
|
||||
DAC_DMACmd(self->dac_channel, ENABLE);
|
||||
|
||||
//printf("DMA: %p %lu\n", bufinfo.buf, bufinfo.len);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_audio_noise_obj, pyb_audio_noise);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_audio_triangle_obj, pyb_audio_triangle);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_audio_dac_obj, pyb_audio_dac);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_audio_dma_obj, 3, pyb_audio_dma);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_audio_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_noise), (mp_obj_t)&pyb_audio_noise_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_triangle), (mp_obj_t)&pyb_audio_triangle_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_dac), (mp_obj_t)&pyb_audio_dac_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_dma), (mp_obj_t)&pyb_audio_dma_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_audio_locals_dict, pyb_audio_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t pyb_audio_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_,
|
||||
.locals_dict = (mp_obj_t)&pyb_audio_locals_dict,
|
||||
};
|
||||
|
||||
STATIC const pyb_audio_t pyb_audio_channel_1 = {{&pyb_audio_type}, DAC_Channel_1, DMA1_Stream5};
|
||||
STATIC const pyb_audio_t pyb_audio_channel_2 = {{&pyb_audio_type}, DAC_Channel_2, DMA1_Stream6};
|
||||
|
||||
// create the audio object
|
||||
// currently support either DAC1 on X5 (id = 1) or DAC2 on X6 (id = 2)
|
||||
|
||||
STATIC mp_obj_t pyb_Audio(mp_obj_t id) {
|
||||
// DAC peripheral clock
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
|
||||
|
||||
int dac_id = mp_obj_get_int(id);
|
||||
uint pin;
|
||||
const pyb_audio_t *dac_obj;
|
||||
|
||||
if (dac_id == 1) {
|
||||
pin = GPIO_Pin_4;
|
||||
dac_obj = &pyb_audio_channel_1;
|
||||
} else {
|
||||
pin = GPIO_Pin_5;
|
||||
dac_obj = &pyb_audio_channel_2;
|
||||
}
|
||||
|
||||
// DAC channel configuration
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = pin;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
// DAC channel Configuration
|
||||
DAC_InitTypeDef DAC_InitStructure;
|
||||
DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
|
||||
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
|
||||
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1023;
|
||||
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
|
||||
DAC_Init(dac_obj->dac_channel, &DAC_InitStructure);
|
||||
|
||||
// Enable DAC Channel
|
||||
DAC_Cmd(dac_obj->dac_channel, ENABLE);
|
||||
|
||||
// from now on use DAC_SetChannel[12]Data to trigger a conversion
|
||||
|
||||
// return static object
|
||||
return (mp_obj_t)dac_obj;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(pyb_Audio_obj, pyb_Audio);
|
@ -1 +0,0 @@
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_Audio_obj);
|
@ -1,38 +0,0 @@
|
||||
#define NETDUINO_PLUS_2
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "NetduinoPlus2"
|
||||
|
||||
#define MICROPY_HW_HAS_SWITCH (1)
|
||||
|
||||
// On the netuino, the sdcard appears to be wired up as a 1-bit
|
||||
// SPI, so the driver needs to be converted to support that before
|
||||
// we can turn this on.
|
||||
#define MICROPY_HW_HAS_SDCARD (0)
|
||||
#define MICROPY_HW_HAS_MMA7660 (0)
|
||||
#define MICROPY_HW_HAS_LIS3DSH (0)
|
||||
#define MICROPY_HW_HAS_LCD (0)
|
||||
#define MICROPY_HW_HAS_WLAN (0)
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
#define MICROPY_HW_ENABLE_RTC (0)
|
||||
#define MICROPY_HW_ENABLE_TIMER (1)
|
||||
#define MICROPY_HW_ENABLE_SERVO (1)
|
||||
#define MICROPY_HW_ENABLE_AUDIO (0)
|
||||
|
||||
// USRSW is pulled low. Pressing the button makes the input go high.
|
||||
#define USRSW_PIN (pin_B11)
|
||||
#define USRSW_PUPD (GPIO_PuPd_NOPULL)
|
||||
#define USRSW_EXTI_EDGE (EXTI_Trigger_Rising)
|
||||
#define USRSW_PRESSED (1)
|
||||
|
||||
/* LED */
|
||||
#define PYB_LED1 (pin_A10) // Blue LED
|
||||
#define PYB_LED2 (pin_C13) // White LED (aka Power)
|
||||
#define PYB_LED3 (pin_A10) // Same as Led(1)
|
||||
#define PYB_LED4 (pin_C13) // Same as Led(2)
|
||||
|
||||
#define PYB_OTYPE (GPIO_OType_PP)
|
||||
|
||||
#define PYB_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
|
||||
#define PYB_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
|
||||
|
||||
#define HSE_VALUE (25000000)
|
@ -1,28 +0,0 @@
|
||||
D0,PC7
|
||||
D1,PC6
|
||||
D2,PA3
|
||||
D3,PA2
|
||||
D4,PB12
|
||||
D5,PB8
|
||||
D6,PB9
|
||||
D7,PA1
|
||||
D8,PA0
|
||||
D9,PA6
|
||||
D10,PB10
|
||||
D11,PB15
|
||||
D12,PB14
|
||||
D13,PB13
|
||||
A0,PC0
|
||||
A1,PC1
|
||||
A2,PC2
|
||||
A3,PC3
|
||||
A4,PC4
|
||||
A5,PC5
|
||||
LED,PA10
|
||||
SW,PB11
|
||||
PWR_LED,PC13
|
||||
PWR_SD,PB1
|
||||
PWR_HDR,PB2
|
||||
PWR_ETH,PC15
|
||||
RST_ETH,PD2
|
||||
|
|
@ -1,32 +0,0 @@
|
||||
#define PYBOARD3
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "PYBv3"
|
||||
|
||||
#define MICROPY_HW_HAS_SWITCH (1)
|
||||
#define MICROPY_HW_HAS_SDCARD (1)
|
||||
#define MICROPY_HW_HAS_MMA7660 (1)
|
||||
#define MICROPY_HW_HAS_LIS3DSH (0)
|
||||
#define MICROPY_HW_HAS_LCD (0)
|
||||
#define MICROPY_HW_HAS_WLAN (0)
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
#define MICROPY_HW_ENABLE_RTC (1)
|
||||
#define MICROPY_HW_ENABLE_TIMER (1)
|
||||
#define MICROPY_HW_ENABLE_SERVO (1)
|
||||
#define MICROPY_HW_ENABLE_AUDIO (0)
|
||||
|
||||
// USRSW has no pullup or pulldown, and pressing the switch makes the input go low
|
||||
#define USRSW_PIN (pin_A13)
|
||||
#define USRSW_PUPD (GPIO_PuPd_UP)
|
||||
#define USRSW_EXTI_EDGE (EXTI_Trigger_Falling)
|
||||
#define USRSW_PRESSED (0)
|
||||
|
||||
/* LED */
|
||||
#define PYB_LED1 (pin_A8) // R1 - red
|
||||
#define PYB_LED2 (pin_A10) // R2 - red
|
||||
#define PYB_LED3 (pin_C4) // G1 - green
|
||||
#define PYB_LED4 (pin_C5) // G2 - green
|
||||
|
||||
#define PYB_OTYPE (GPIO_OType_PP)
|
||||
|
||||
#define PYB_LED_ON(pin) (pin->gpio->BSRRH = pin->pin_mask)
|
||||
#define PYB_LED_OFF(pin) (pin->gpio->BSRRL = pin->pin_mask)
|
@ -1,37 +0,0 @@
|
||||
B13,PB13
|
||||
B14,PB14
|
||||
B15,PB15
|
||||
C6,PC6
|
||||
C7,PC7
|
||||
A13,PA13
|
||||
A14,PA14
|
||||
A15,PA15
|
||||
B3,PB3
|
||||
B4,PB4
|
||||
B6,PB6
|
||||
B7,PB7
|
||||
B8,PB8
|
||||
B9,PB9
|
||||
C0,PC0
|
||||
C1,PC1
|
||||
C2,PC2
|
||||
C3,PC3
|
||||
A0,PA0
|
||||
A1,PA1
|
||||
A2,PA2
|
||||
A3,PA3
|
||||
A4,PA4
|
||||
A5,PA5
|
||||
A6,PA6
|
||||
A7,PA7
|
||||
B0,PB0
|
||||
B1,PB1
|
||||
B10,PB10
|
||||
B11,PB11
|
||||
B12,PB12
|
||||
LED_R1,PA8
|
||||
LED_R2,PA10
|
||||
LED_G1,PC4
|
||||
LED_G2,PC5
|
||||
SW,PA13
|
||||
|
|
@ -1,33 +0,0 @@
|
||||
#define PYBOARD4
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "PYBv4"
|
||||
|
||||
#define MICROPY_HW_HAS_SWITCH (1)
|
||||
#define MICROPY_HW_HAS_SDCARD (1)
|
||||
#define MICROPY_HW_HAS_MMA7660 (1)
|
||||
#define MICROPY_HW_HAS_LIS3DSH (0)
|
||||
#define MICROPY_HW_HAS_LCD (1)
|
||||
#define MICROPY_HW_HAS_WLAN (0)
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
#define MICROPY_HW_ENABLE_RTC (1)
|
||||
#define MICROPY_HW_ENABLE_TIMER (1)
|
||||
#define MICROPY_HW_ENABLE_SERVO (1)
|
||||
#define MICROPY_HW_ENABLE_AUDIO (1)
|
||||
|
||||
// USRSW has no pullup or pulldown, and pressing the switch makes the input go low
|
||||
#define USRSW_PIN (pin_B3)
|
||||
#define USRSW_PUPD (GPIO_PuPd_UP)
|
||||
#define USRSW_EXTI_EDGE (EXTI_Trigger_Falling)
|
||||
#define USRSW_PRESSED (0)
|
||||
|
||||
/* LED */
|
||||
#define PYB_LED1 (pin_A13) // red
|
||||
#define PYB_LED2 (pin_A14) // green
|
||||
#define PYB_LED3 (pin_A15) // yellow
|
||||
#define PYB_LED4 (pin_B4) // blue
|
||||
|
||||
#define PYB_OTYPE (GPIO_OType_PP)
|
||||
|
||||
#define PYB_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
|
||||
#define PYB_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
|
||||
|
@ -1,45 +0,0 @@
|
||||
X1,PA0
|
||||
X2,PA1
|
||||
X3,PA2
|
||||
X4,PA3
|
||||
X5,PA4
|
||||
X6,PA5
|
||||
X7,PA6
|
||||
X8,PA7
|
||||
X9,PB6
|
||||
X10,PB7
|
||||
X11,PC4
|
||||
X12,PC5
|
||||
X13,Reset
|
||||
X14,GND
|
||||
X15,3.3V
|
||||
X16,VIN
|
||||
X17,PB3
|
||||
X18,PC13
|
||||
X19,PC0
|
||||
X20,PC1
|
||||
X21,PC2
|
||||
X22,PC3
|
||||
X23,A3.3V
|
||||
X24,AGND
|
||||
Y1,PC6
|
||||
Y2,PC7
|
||||
Y3,PB8
|
||||
Y4,PB9
|
||||
Y5,PB12
|
||||
Y6,PB13
|
||||
Y7,PB14
|
||||
Y8,PB15
|
||||
Y9,PB10
|
||||
Y10,PB11
|
||||
Y11,PB0
|
||||
Y12,PB1
|
||||
Y13,Reset
|
||||
Y14,GND
|
||||
Y15,3.3V
|
||||
Y16,VIN
|
||||
LED_BLUE,PB4
|
||||
LED_RED,PA13
|
||||
LED_GREEN,PA14
|
||||
LED_YELLOW,PA15
|
||||
SW,PB3
|
|
@ -1,33 +0,0 @@
|
||||
#define STM32F4DISC
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "F4DISC"
|
||||
|
||||
#define MICROPY_HW_HAS_SWITCH (1)
|
||||
#define MICROPY_HW_HAS_SDCARD (0)
|
||||
#define MICROPY_HW_HAS_MMA7660 (0)
|
||||
#define MICROPY_HW_HAS_LIS3DSH (1)
|
||||
#define MICROPY_HW_HAS_LCD (0)
|
||||
#define MICROPY_HW_HAS_WLAN (0)
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
#define MICROPY_HW_ENABLE_RTC (1)
|
||||
#define MICROPY_HW_ENABLE_TIMER (1)
|
||||
#define MICROPY_HW_ENABLE_SERVO (0)
|
||||
#define MICROPY_HW_ENABLE_AUDIO (0)
|
||||
|
||||
// USRSW is pulled low. Pressing the button makes the input go high.
|
||||
#define USRSW_PIN (pin_A0)
|
||||
#define USRSW_PUPD (GPIO_PuPd_NOPULL)
|
||||
#define USRSW_EXTI_EDGE (EXTI_Trigger_Rising)
|
||||
#define USRSW_PRESSED (1)
|
||||
|
||||
/* LED */
|
||||
#define PYB_LED1 (pin_D14) // red
|
||||
#define PYB_LED2 (pin_D12) // green
|
||||
#define PYB_LED3 (pin_D13) // orange
|
||||
#define PYB_LED4 (pin_D15) // blue
|
||||
|
||||
#define PYB_OTYPE (GPIO_OType_PP)
|
||||
|
||||
#define PYB_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
|
||||
#define PYB_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
|
||||
|
@ -1,85 +0,0 @@
|
||||
PC0,PC0
|
||||
PC1,PC1
|
||||
PC2,PC2
|
||||
PC3,PC3
|
||||
PA0,PA0
|
||||
PA1,PA1
|
||||
PA2,PA2
|
||||
PA3,PA3
|
||||
PA4,PA4
|
||||
PA5,PA5
|
||||
PA6,PA6
|
||||
PA7,PA7
|
||||
PC4,PC4
|
||||
PC5,PC5
|
||||
PB0,PB0
|
||||
PB1,PB1
|
||||
PB2,PB2
|
||||
PE7,PE7
|
||||
PE8,PE8
|
||||
PE9,PE9
|
||||
PE10,PE10
|
||||
PE11,PE11
|
||||
PE12,PE12
|
||||
PE13,PE13
|
||||
PE14,PE14
|
||||
PE15,PE15
|
||||
PB10,PB10
|
||||
PB11,PB11
|
||||
PB12,PB12
|
||||
PB13,PB13
|
||||
PB14,PB14
|
||||
PB15,PB15
|
||||
PD8,PD8
|
||||
PD9,PD9
|
||||
PD10,PD10
|
||||
PD11,PD11
|
||||
PD12,PD12
|
||||
PD13,PD13
|
||||
PD14,PD14
|
||||
PD15,PD15
|
||||
PC6,PC6
|
||||
PC7,PC7
|
||||
PC8,PC8
|
||||
PC9,PC9
|
||||
PA8,PA8
|
||||
PA9,PA9
|
||||
PA10,PA10
|
||||
PA13,PA13
|
||||
PA14,PA14
|
||||
PA15,PA15
|
||||
PC10,PC10
|
||||
PC11,PC11
|
||||
PC12,PC12
|
||||
PD0,PD0
|
||||
PD1,PD1
|
||||
PD2,PD2
|
||||
PD3,PD3
|
||||
PD4,PD4
|
||||
PD5,PD5
|
||||
PD6,PD6
|
||||
PD7,PD7
|
||||
PB4,PB4
|
||||
PB5,PB5
|
||||
PB6,PB6
|
||||
PB7,PB7
|
||||
PB8,PB8
|
||||
PB9,PB9
|
||||
PE0,PE0
|
||||
PE1,PE1
|
||||
PE2,PE2
|
||||
PE3,PE3
|
||||
PE4,PE4
|
||||
PE5,PE5
|
||||
PE6,PE6
|
||||
PC13,PC13
|
||||
PC14,PC14
|
||||
PC15,PC15
|
||||
PH0,PH0
|
||||
PH1,PH1
|
||||
LED_GREEN,PD12
|
||||
LED_ORANGE,PD13
|
||||
LED_RED,PD14
|
||||
LED_BLUE,PD15
|
||||
SW,PA0
|
||||
|
|
@ -1,261 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""Creates the pin file for the STM32F4xx."""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import csv
|
||||
|
||||
SUPPORTED_FN = {
|
||||
'TIM' : ['CH1', 'CH2', 'CH3', 'CH4',
|
||||
'CH1N', 'CH2N', 'CH3N', 'CH1_ETR', 'ETR', 'BKIN'],
|
||||
'I2C' : ['SDA', 'SCL'],
|
||||
'USART' : ['RX', 'TX', 'CTS', 'RTS', 'CK'],
|
||||
'UART' : ['RX', 'TX', 'CTS', 'RTS'],
|
||||
'SPI' : ['NSS', 'SCK', 'MISO', 'MOSI']
|
||||
}
|
||||
|
||||
def parse_port_pin(name_str):
|
||||
"""Parses a string and returns a (port-num, pin-num) tuple."""
|
||||
if len(name_str) < 3:
|
||||
raise ValueError("Expecting pin name to be at least 3 charcters.")
|
||||
if name_str[0] != 'P':
|
||||
raise ValueError("Expecting pin name to start with P")
|
||||
if name_str[1] < 'A' or name_str[1] > 'J':
|
||||
raise ValueError("Expecting pin port to be between A and J")
|
||||
port = ord(name_str[1]) - ord('A')
|
||||
pin_str = name_str[2:]
|
||||
if not pin_str.isdigit():
|
||||
raise ValueError("Expecting numeric pin number.")
|
||||
return (port, int(pin_str))
|
||||
|
||||
def split_name_num(name_num):
|
||||
num = None
|
||||
for num_idx in range(len(name_num) - 1, -1, -1):
|
||||
if not name_num[num_idx].isdigit():
|
||||
name = name_num[0:num_idx + 1]
|
||||
num_str = name_num[num_idx + 1:]
|
||||
if len(num_str) > 0:
|
||||
num = int(num_str)
|
||||
break
|
||||
return name, num
|
||||
|
||||
|
||||
class AlternateFunction(object):
|
||||
"""Holds the information associated with a pins alternate function."""
|
||||
|
||||
def __init__(self, idx, af_str):
|
||||
self.idx = idx
|
||||
self.af_str = af_str
|
||||
|
||||
self.func = ''
|
||||
self.fn_num = None
|
||||
self.pin_type = ''
|
||||
self.supported = False
|
||||
|
||||
af_words = af_str.split('_', 1)
|
||||
self.func, self.fn_num = split_name_num(af_words[0])
|
||||
if len(af_words) > 1:
|
||||
self.pin_type = af_words[1]
|
||||
if self.func in SUPPORTED_FN:
|
||||
pin_types = SUPPORTED_FN[self.func]
|
||||
if self.pin_type in pin_types:
|
||||
self.supported = True
|
||||
|
||||
def is_supported(self):
|
||||
return self.supported
|
||||
|
||||
def ptr(self):
|
||||
"""Returns the numbered function (i.e. USART6) for this AF."""
|
||||
if self.fn_num is None:
|
||||
return self.func
|
||||
return '{:s}{:d}'.format(self.func, self.fn_num)
|
||||
|
||||
def print(self):
|
||||
"""Prints the C representation of this AF."""
|
||||
if self.supported:
|
||||
print(' AF', end='')
|
||||
else:
|
||||
print(' //', end='')
|
||||
fn_num = self.fn_num
|
||||
if fn_num is None:
|
||||
fn_num = 0
|
||||
print('({:2d}, {:8s}, {:2d}, {:10s}, {:8s}), // {:s}'.format(self.idx,
|
||||
self.func, fn_num, self.pin_type, self.ptr(), self.af_str))
|
||||
|
||||
|
||||
class Pin(object):
|
||||
"""Holds the information associated with a pin."""
|
||||
|
||||
def __init__(self, port, pin):
|
||||
self.port = port
|
||||
self.pin = pin
|
||||
self.alt_fn = []
|
||||
self.board_name = None
|
||||
self.alt_fn_count = 0
|
||||
|
||||
def port_letter(self):
|
||||
return chr(self.port + ord('A'))
|
||||
|
||||
def pin_name(self):
|
||||
return '{:s}{:d}'.format(self.port_letter(), self.pin)
|
||||
|
||||
def parse_af(self, af_idx, af_strs_in):
|
||||
if len(af_strs_in) == 0:
|
||||
return
|
||||
# If there is a slash, then the slash separates 2 aliases for the
|
||||
# same alternate function.
|
||||
af_strs = af_strs_in.split('/')
|
||||
for af_str in af_strs:
|
||||
alt_fn = AlternateFunction(af_idx, af_str)
|
||||
self.alt_fn.append(alt_fn)
|
||||
if alt_fn.is_supported():
|
||||
self.alt_fn_count += 1
|
||||
|
||||
def alt_fn_name(self):
|
||||
if self.alt_fn_count > 0:
|
||||
return 'pin_{:s}_af'.format(self.pin_name())
|
||||
return 'NULL'
|
||||
|
||||
def print(self):
|
||||
if self.alt_fn_count == 0:
|
||||
print("// ", end='')
|
||||
print('const pin_af_obj_t {:s}[] = {{'.format(self.alt_fn_name()))
|
||||
for alt_fn in self.alt_fn:
|
||||
alt_fn.print()
|
||||
if self.alt_fn_count == 0:
|
||||
print("// ", end='')
|
||||
print('};')
|
||||
print('')
|
||||
print('const pin_obj_t pin_{:s} = PIN({:s}, {:d}, {:d}, {:s});'.format(
|
||||
self.pin_name(), self.port_letter(), self.pin,
|
||||
self.alt_fn_count, self.alt_fn_name()))
|
||||
print('')
|
||||
|
||||
def print_header(self, hdr_file):
|
||||
hdr_file.write('extern const pin_obj_t pin_{:s};\n'.
|
||||
format(self.pin_name()))
|
||||
if self.alt_fn_count > 0:
|
||||
hdr_file.write('extern const pin_af_obj_t pin_{:s}_af[];\n'.
|
||||
format(self.pin_name()))
|
||||
|
||||
|
||||
class Pins(object):
|
||||
|
||||
def __init__(self):
|
||||
self.pins = []
|
||||
self.board_pins = []
|
||||
|
||||
def find_pin(self, port_num, pin_num):
|
||||
for pin in self.pins:
|
||||
if pin.port == port_num and pin.pin == pin_num:
|
||||
return pin
|
||||
|
||||
def parse_af_file(self, filename, pinname_col, af_col):
|
||||
with open(filename, 'r') as csvfile:
|
||||
rows = csv.reader(csvfile)
|
||||
for row in rows:
|
||||
try:
|
||||
(port_num, pin_num) = parse_port_pin(row[pinname_col])
|
||||
except:
|
||||
continue
|
||||
pin = Pin(port_num, pin_num)
|
||||
for af_idx in range(af_col, len(row)):
|
||||
pin.parse_af(af_idx - af_col, row[af_idx])
|
||||
self.pins.append(pin)
|
||||
|
||||
def parse_board_file(self, filename):
|
||||
with open(filename, 'r') as csvfile:
|
||||
rows = csv.reader(csvfile)
|
||||
for row in rows:
|
||||
try:
|
||||
(port_num, pin_num) = parse_port_pin(row[1])
|
||||
except:
|
||||
continue
|
||||
pin = self.find_pin(port_num, pin_num)
|
||||
if pin:
|
||||
pin.board_name = row[0]
|
||||
self.board_pins.append(pin)
|
||||
|
||||
def print_named(self, label, pins):
|
||||
print('const pin_named_pin_t pin_{:s}_pins[] = {{'.format(label))
|
||||
for pin in pins:
|
||||
if pin.board_name:
|
||||
if label == 'board':
|
||||
pin_name = pin.board_name
|
||||
else:
|
||||
pin_name = pin.pin_name()
|
||||
print(' {{ "{:s}", &pin_{:s} }},'.format(pin_name, pin.pin_name()))
|
||||
print(' { NULL, NULL }')
|
||||
print('};')
|
||||
|
||||
def print(self):
|
||||
for pin in self.pins:
|
||||
if pin.board_name:
|
||||
pin.print()
|
||||
self.print_named('cpu', self.pins)
|
||||
print('')
|
||||
self.print_named('board', self.board_pins)
|
||||
|
||||
def print_header(self, hdr_filename):
|
||||
with open(hdr_filename, 'wt') as hdr_file:
|
||||
for pin in self.pins:
|
||||
if pin.board_name:
|
||||
pin.print_header(hdr_file)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="make-pins.py",
|
||||
usage="%(prog)s [options] [command]",
|
||||
description="Generate board specific pin file"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-a", "--af",
|
||||
dest="af_filename",
|
||||
help="Specifies the alternate function file for the chip",
|
||||
default="stm32f4xx-af.csv"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-b", "--board",
|
||||
dest="board_filename",
|
||||
help="Specifies the board file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p", "--prefix",
|
||||
dest="prefix_filename",
|
||||
help="Specifies beginning portion of generated pins file",
|
||||
default="stm32f4xx-prefix.c"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-r", "--hdr",
|
||||
dest="hdr_filename",
|
||||
help="Specifies name of generated pin header file",
|
||||
default="build/pins.h"
|
||||
)
|
||||
args = parser.parse_args(sys.argv[1:])
|
||||
|
||||
pins = Pins()
|
||||
|
||||
print('// This file was automatically generated by make-pins.py')
|
||||
print('//')
|
||||
if args.af_filename:
|
||||
print('// --af {:s}'.format(args.af_filename))
|
||||
pins.parse_af_file(args.af_filename, 1, 2)
|
||||
|
||||
if args.board_filename:
|
||||
print('// --board {:s}'.format(args.board_filename))
|
||||
pins.parse_board_file(args.board_filename)
|
||||
|
||||
if args.prefix_filename:
|
||||
print('// --prefix {:s}'.format(args.prefix_filename))
|
||||
print('')
|
||||
with open(args.prefix_filename, 'r') as prefix_file:
|
||||
print(prefix_file.read())
|
||||
pins.print()
|
||||
pins.print_header(args.hdr_filename)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,142 +0,0 @@
|
||||
Port,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15
|
||||
,,SYS,TIM1/2,TIM3/4/5,TIM8/9/10/11,I2C1/2/3,SPI1/SPI2/I2S2/I2S2ext,SPI3/I2Sext/I2S3,USART1/2/3/I2S3ext,UART4/5/USART6,CAN1/CAN2/TIM12/13/14,OTG_FS/OTG_HS,ETH,FSMC/SDIO/OTG_FS,DCMI,,
|
||||
PortA,PA0,,TIM2_CH1_ETR,TIM5_CH1,TIM8_ETR,,,,USART2_CTS,UART4_TX,,,ETH_MII_CRS,,,,EVENTOUT
|
||||
PortA,PA1,,TIM2_CH2,TIM5_CH2,,,,,USART2_RTS,UART4_RX,,,ETH_MII_RX_CLK/ETH_RMII__REF_CLK,,,,EVENTOUT
|
||||
PortA,PA2,,TIM2_CH3,TIM5_CH3,TIM9_CH1,,,,USART2_TX,,,,ETH_MDIO,,,,EVENTOUT
|
||||
PortA,PA3,,TIM2_CH4,TIM5_CH4,TIM9_CH2,,,,USART2_RX,,,OTG_HS_ULPI_D0,ETH_MII_COL,,,,EVENTOUT
|
||||
PortA,PA4,,,,,,SPI1_NSS,SPI3_NSS/I2S3_WS,USART2_CK,,,,,OTG_HS_SOF,DCMI_HSYNC,,EVENTOUT
|
||||
PortA,PA5,,TIM2_CH1_ETR,,TIM8_CH1N,,SPI1_SCK,,,,,OTG_HS_ULPI_CK,,,,,EVENTOUT
|
||||
PortA,PA6,,TIM1_BKIN,TIM3_CH1,TIM8_BKIN,,SPI1_MISO,,,,TIM13_CH1,,,,DCMI_PIXCK,,EVENTOUT
|
||||
PortA,PA7,,TIM1_CH1N,TIM3_CH2,TIM8_CH1N,,SPI1_MOSI,,,,TIM14_CH1,,ETH_MII_RX_DV/ETH_RMII_CRS_DV,,,,EVENTOUT
|
||||
PortA,PA8,MCO1,TIM1_CH1,,,I2C3_SCL,,,USART1_CK,,,OTG_FS_SOF,,,,,EVENTOUT
|
||||
PortA,PA9,,TIM1_CH2,,,I2C3_SMBA,,,USART1_TX,,,,,,DCMI_D0,,EVENTOUT
|
||||
PortA,PA10,,TIM1_CH3,,,,,,USART1_RX,,,OTG_FS_ID,,,DCMI_D1,,EVENTOUT
|
||||
PortA,PA11,,TIM1_CH4,,,,,,USART1_CTS,,CAN1_RX,OTG_FS_DM,,,,,EVENTOUT
|
||||
PortA,PA12,,TIM1_ETR,,,,,,USART1_RTS,,CAN1_TX,OTG_FS_DP,,,,,EVENTOUT
|
||||
PortA,PA13,JTMS-SWDIO,,,,,,,,,,,,,,,EVENTOUT
|
||||
PortA,PA14,JTCK-SWCLK,,,,,,,,,,,,,,,EVENTOUT
|
||||
PortA,PA15,JTDI,TIM2_CH1/TIM2_ETR,,,,SPI1_NSS,SPI3_NSS/I2S3_WS,,,,,,,,,EVENTOUT
|
||||
PortB,PB0,,TIM1_CH2N,TIM3_CH3,TIM8_CH2N,,,,,,,OTG_HS_ULPI_D1,ETH_MII_RXD2,,,,EVENTOUT
|
||||
PortB,PB1,,TIM1_CH3N,TIM3_CH4,TIM8_CH3N,,,,,,,OTG_HS_ULPI_D2,ETH_MII_RXD3,,,,EVENTOUT
|
||||
PortB,PB2,,,,,,,,,,,,,,,,EVENTOUT
|
||||
PortB,PB3,JTDO/TRACESWO,TIM2_CH2,,,,SPI1_SCK,SPI3_SCKI2S3_CK,,,,,,,,,EVENTOUT
|
||||
PortB,PB4,NJTRST,,TIM3_CH1,,,SPI1_MISO,SPI3_MISO,I2S3ext_SD,,,,,,,,EVENTOUT
|
||||
PortB,PB5,,,TIM3_CH2,,I2C1_SMBA,SPI1_MOSI,SPI3_MOSI/I2S3_SD,,,CAN2_RX,OTG_HS_ULPI_D7,ETH_PPS_OUT,,DCMI_D10,,EVENTOUT
|
||||
PortB,PB6,,,TIM4_CH1,,I2C1_SCL,,,USART1_TX,,CAN2_TX,,,,DCMI_D5,,EVENTOUT
|
||||
PortB,PB7,,,TIM4_CH2,,I2C1_SDA,,,USART1_RX,,,,,FSMC_NL,DCMI_VSYNC,,EVENTOUT
|
||||
PortB,PB8,,,TIM4_CH3,TIM10_CH1,I2C1_SCL,,,,,CAN1_RX,,ETH_MII_TXD3,SDIO_D4,DCMI_D6,,EVENTOUT
|
||||
PortB,PB9,,,TIM4_CH4,TIM11_CH1,I2C1_SDA,SPI2_NSS/I2S2_WS,,,,CAN1_TX,,,SDIO_D5,DCMI_D7,,EVENTOUT
|
||||
PortB,PB10,,TIM2_CH3,,,I2C2_SCL,SPI2_SCKI2S2_CK,,USART3_TX,,,OTG_HS_ULPI_D3,ETH_MII_RX_ER,,,,EVENTOUT
|
||||
PortB,PB11,,TIM2_CH4,,,I2C2_SDA,,,USART3_RX,,,OTG_HS_ULPI_D4,ETH_MII_TX_EN/ETH_RMII_TX_EN,,,,EVENTOUT
|
||||
PortB,PB12,,TIM1_BKIN,,,I2C2_SMBA,SPI2_NSS/I2S2_WS,,USART3_CK,,CAN2_RX,OTG_HS_ULPI_D5,ETH_MII_TXD0/ETH_RMII_TXD0,OTG_HS_ID,,,EVENTOUT
|
||||
PortB,PB13,,TIM1_CH1N,,,,SPI2_SCKI2S2_CK,,USART3_CTS,,CAN2_TX,OTG_HS_ULPI_D6,ETH_MII_TXD1/ETH_RMII_TXD1,,,,EVENTOUT
|
||||
PortB,PB14,,TIM1_CH2N,,TIM8_CH2N,,SPI2_MISO,I2S2ext_SD,USART3_RTS,,TIM12_CH1,,,OTG_HS_DM,,,EVENTOUT
|
||||
PortB,PB15,RTC_REFIN,TIM1_CH3N,,TIM8_CH3N,,SPI2_MOSI/I2S2_SD,,,,TIM12_CH2,,,OTG_HS_DP,,,EVENTOUT
|
||||
PortC,PC0,,,,,,,,,,,OTG_HS_ULPI_STP,,,,,EVENTOUT
|
||||
PortC,PC1,,,,,,,,,,,,ETH_MDC,,,,EVENTOUT
|
||||
PortC,PC2,,,,,,SPI2_MISO,I2S2ext_SD,,,,OTG_HS_ULPI_DIR,ETH_MII_TXD2,,,,EVENTOUT
|
||||
PortC,PC3,,,,,,SPI2_MOSI/I2S2_SD,,,,,OTG_HS_ULPI_NXT,ETH_MII_TX_CLK,,,,EVENTOUT
|
||||
PortC,PC4,,,,,,,,,,,,ETH_MII_RXD0/ETH_RMII_RXD0,,,,EVENTOUT
|
||||
PortC,PC5,,,,,,,,,,,,ETH_MII_RXD1/ETH_RMII_RXD1,,,,EVENTOUT
|
||||
PortC,PC6,,,TIM3_CH1,TIM8_CH1,,I2S2_MCK,,,USART6_TX,,,,SDIO_D6,DCMI_D0,,EVENTOUT
|
||||
PortC,PC7,,,TIM3_CH2,TIM8_CH2,,,I2S3_MCK,,USART6_RX,,,,SDIO_D7,DCMI_D1,,EVENTOUT
|
||||
PortC,PC8,,,TIM3_CH3,TIM8_CH3,,,,,USART6_CK,,,,SDIO_D0,DCMI_D2,,EVENTOUT
|
||||
PortC,PC9,MCO2,,TIM3_CH4,TIM8_CH4,I2C3_SDA,I2S_CKIN,,,,,,,SDIO_D1,DCMI_D3,,EVENTOUT
|
||||
PortC,PC10,,,,,,,SPI3_SCK/I2S3_CK,USART3_TX,UART4_TX,,,,SDIO_D2,DCMI_D8,,EVENTOUT
|
||||
PortC,PC11,,,,,,I2S3ext_SD,SPI3_MISO,USART3_RX,UART4_RX,,,,SDIO_D3,DCMI_D4,,EVENTOUT
|
||||
PortC,PC12,,,,,,,SPI3_MOSI/I2S3_SD,USART3_CK,UART5_TX,,,,SDIO_CK,DCMI_D9,,EVENTOUT
|
||||
PortC,PC13,,,,,,,,,,,,,,,,EVENTOUT
|
||||
PortC,PC14,,,,,,,,,,,,,,,,EVENTOUT
|
||||
PortC,PC15,,,,,,,,,,,,,,,,EVENTOUT
|
||||
PortD,PD0,,,,,,,,,,CAN1_RX,,,FSMC_D2,,,EVENTOUT
|
||||
PortD,PD1,,,,,,,,,,CAN1_TX,,,FSMC_D3,,,EVENTOUT
|
||||
PortD,PD2,,,TIM3_ETR,,,,,,UART5_RX,,,,SDIO_CMD,DCMI_D11,,EVENTOUT
|
||||
PortD,PD3,,,,,,,,USART2_CTS,,,,,FSMC_CLK,,,EVENTOUT
|
||||
PortD,PD4,,,,,,,,USART2_RTS,,,,,FSMC_NOE,,,EVENTOUT
|
||||
PortD,PD5,,,,,,,,USART2_TX,,,,,FSMC_NWE,,,EVENTOUT
|
||||
PortD,PD6,,,,,,,,USART2_RX,,,,,FSMC_NWAIT,,,EVENTOUT
|
||||
PortD,PD7,,,,,,,,USART2_CK,,,,,FSMC_NE1/FSMC_NCE2,,,EVENTOUT
|
||||
PortD,PD8,,,,,,,,USART3_TX,,,,,FSMC_D13,,,EVENTOUT
|
||||
PortD,PD9,,,,,,,,USART3_RX,,,,,FSMC_D14,,,EVENTOUT
|
||||
PortD,PD10,,,,,,,,USART3_CK,,,,,FSMC_D15,,,EVENTOUT
|
||||
PortD,PD11,,,,,,,,USART3_CTS,,,,,FSMC_A16,,,EVENTOUT
|
||||
PortD,PD12,,,TIM4_CH1,,,,,USART3_RTS,,,,,FSMC_A17,,,EVENTOUT
|
||||
PortD,PD13,,,TIM4_CH2,,,,,,,,,,FSMC_A18,,,EVENTOUT
|
||||
PortD,PD14,,,TIM4_CH3,,,,,,,,,,FSMC_D0,,,EVENTOUT
|
||||
PortD,PD15,,,TIM4_CH4,,,,,,,,,,FSMC_D1,,,EVENTOUT
|
||||
PortE,PE0,,,TIM4_ETR,,,,,,,,,,FSMC_NBL0,DCMI_D2,,EVENTOUT
|
||||
PortE,PE1,,,,,,,,,,,,,FSMC_NBL1,DCMI_D3,,EVENTOUT
|
||||
PortE,PE2,TRACECLK,,,,,,,,,,,ETH_MII_TXD3,FSMC_A23,,,EVENTOUT
|
||||
PortE,PE3,TRACED0,,,,,,,,,,,,FSMC_A19,,,EVENTOUT
|
||||
PortE,PE4,TRACED1,,,,,,,,,,,,FSMC_A20,DCMI_D4,,EVENTOUT
|
||||
PortE,PE5,TRACED2,,,TIM9_CH1,,,,,,,,,FSMC_A21,DCMI_D6,,EVENTOUT
|
||||
PortE,PE6,TRACED3,,,TIM9_CH2,,,,,,,,,FSMC_A22,DCMI_D7,,EVENTOUT
|
||||
PortE,PE7,,TIM1_ETR,,,,,,,,,,,FSMC_D4,,,EVENTOUT
|
||||
PortE,PE8,,TIM1_CH1N,,,,,,,,,,,FSMC_D5,,,EVENTOUT
|
||||
PortE,PE9,,TIM1_CH1,,,,,,,,,,,FSMC_D6,,,EVENTOUT
|
||||
PortE,PE10,,TIM1_CH2N,,,,,,,,,,,FSMC_D7,,,EVENTOUT
|
||||
PortE,PE11,,TIM1_CH2,,,,,,,,,,,FSMC_D8,,,EVENTOUT
|
||||
PortE,PE12,,TIM1_CH3N,,,,,,,,,,,FSMC_D9,,,EVENTOUT
|
||||
PortE,PE13,,TIM1_CH3,,,,,,,,,,,FSMC_D10,,,EVENTOUT
|
||||
PortE,PE14,,TIM1_CH4,,,,,,,,,,,FSMC_D11,,,EVENTOUT
|
||||
PortE,PE15,,TIM1_BKIN,,,,,,,,,,,FSMC_D12,,,EVENTOUT
|
||||
PortF,PF0,,,,,I2C2_SDA,,,,,,,,FSMC_A0,,,EVENTOUT
|
||||
PortF,PF1,,,,,I2C2_SCL,,,,,,,,FSMC_A1,,,EVENTOUT
|
||||
PortF,PF2,,,,,I2C2_SMBA,,,,,,,,FSMC_A2,,,EVENTOUT
|
||||
PortF,PF3,,,,,,,,,,,,,FSMC_A3,,,EVENTOUT
|
||||
PortF,PF4,,,,,,,,,,,,,FSMC_A4,,,EVENTOUT
|
||||
PortF,PF5,,,,,,,,,,,,,FSMC_A5,,,EVENTOUT
|
||||
PortF,PF6,,,,TIM10_CH1,,,,,,,,,FSMC_NIORD,,,EVENTOUT
|
||||
PortF,PF7,,,,TIM11_CH1,,,,,,,,,FSMC_NREG,,,EVENTOUT
|
||||
PortF,PF8,,,,,,,,,,TIM13_CH1,,,FSMC_NIOWR,,,EVENTOUT
|
||||
PortF,PF9,,,,,,,,,,TIM14_CH1,,,FSMC_CD,,,EVENTOUT
|
||||
PortF,PF10,,,,,,,,,,,,,FSMC_INTR,,,EVENTOUT
|
||||
PortF,PF11,,,,,,,,,,,,,,DCMI_D12,,EVENTOUT
|
||||
PortF,PF12,,,,,,,,,,,,,FSMC_A6,,,EVENTOUT
|
||||
PortF,PF13,,,,,,,,,,,,,FSMC_A7,,,EVENTOUT
|
||||
PortF,PF14,,,,,,,,,,,,,FSMC_A8,,,EVENTOUT
|
||||
PortF,PF15,,,,,,,,,,,,,FSMC_A9,,,EVENTOUT
|
||||
PortG,PG0,,,,,,,,,,,,,FSMC_A10,,,EVENTOUT
|
||||
PortG,PG1,,,,,,,,,,,,,FSMC_A11,,,EVENTOUT
|
||||
PortG,PG2,,,,,,,,,,,,,FSMC_A12,,,EVENTOUT
|
||||
PortG,PG3,,,,,,,,,,,,,FSMC_A13,,,EVENTOUT
|
||||
PortG,PG4,,,,,,,,,,,,,FSMC_A14,,,EVENTOUT
|
||||
PortG,PG5,,,,,,,,,,,,,FSMC_A15,,,EVENTOUT
|
||||
PortG,PG6,,,,,,,,,,,,,FSMC_INT2,,,EVENTOUT
|
||||
PortG,PG7,,,,,,,,,USART6_CK,,,,FSMC_INT3,,,EVENTOUT
|
||||
PortG,PG8,,,,,,,,,USART6_RTS,,,ETH_PPS_OUT,,,,EVENTOUT
|
||||
PortG,PG9,,,,,,,,,USART6_RX,,,,FSMC_NE2/FSMC_NCE3,,,EVENTOUT
|
||||
PortG,PG10,,,,,,,,,,,,,FSMC_NCE4_1/FSMC_NE3,,,EVENTOUT
|
||||
PortG,PG11,,,,,,,,,,,,ETH_MII_TX_EN/ETH_RMII_TX_EN,FSMC_NCE4_2,,,EVENTOUT
|
||||
PortG,PG12,,,,,,,,,USART6_RTS,,,,FSMC_NE4,,,EVENTOUT
|
||||
PortG,PG13,,,,,,,,,USART6_CTS,,,ETH_MII_TXD0/ETH_RMII_TXD0,FSMC_A24,,,EVENTOUT
|
||||
PortG,PG14,,,,,,,,,USART6_TX,,,ETH_MII_TXD1/ETH_RMII_TXD1,FSMC_A25,,,EVENTOUT
|
||||
PortG,PG15,,,,,,,,,USART6_CTS,,,,,DCMI_D13,,EVENTOUT
|
||||
PortH,PH0,,,,,,,,,,,,,,,,EVENTOUT
|
||||
PortH,PH1,,,,,,,,,,,,,,,,EVENTOUT
|
||||
PortH,PH2,,,,,,,,,,,,ETH_MII_CRS,,,,EVENTOUT
|
||||
PortH,PH3,,,,,,,,,,,,ETH_MII_COL,,,,EVENTOUT
|
||||
PortH,PH4,,,,,I2C2_SCL,,,,,,OTG_HS_ULPI_NXT,,,,,EVENTOUT
|
||||
PortH,PH5,,,,,I2C2_SDA,,,,,,,,,,,EVENTOUT
|
||||
PortH,PH6,,,,,I2C2_SMBA,,,,,TIM12_CH1,,ETH_MII_RXD2,,,,EVENTOUT
|
||||
PortH,PH7,,,,,I2C3_SCL,,,,,,,ETH_MII_RXD3,,,,EVENTOUT
|
||||
PortH,PH8,,,,,I2C3_SDA,,,,,,,,,DCMI_HSYNC,,EVENTOUT
|
||||
PortH,PH9,,,,,I2C3_SMBA,,,,,TIM12_CH2,,,,DCMI_D0,,EVENTOUT
|
||||
PortH,PH10,,,TIM5_CH1,,,,,,,,,,,DCMI_D1,,EVENTOUT
|
||||
PortH,PH11,,,TIM5_CH2,,,,,,,,,,,DCMI_D2,,EVENTOUT
|
||||
PortH,PH12,,,TIM5_CH3,,,,,,,,,,,DCMI_D3,,EVENTOUT
|
||||
PortH,PH13,,,,TIM8_CH1N,,,,,,CAN1_TX,,,,,,EVENTOUT
|
||||
PortH,PH14,,,,TIM8_CH2N,,,,,,,,,,DCMI_D4,,EVENTOUT
|
||||
PortH,PH15,,,,TIM8_CH3N,,,,,,,,,,DCMI_D11,,EVENTOUT
|
||||
PortI,PI0,,,TIM5_CH4,,,SPI2_NSS/I2S2_WS,,,,,,,,DCMI_D13,,EVENTOUT
|
||||
PortI,PI1,,,,,,SPI2_SCKI2S2_CK,,,,,,,,DCMI_D8,,EVENTOUT
|
||||
PortI,PI2,,,,TIM8_CH4,,SPI2_MISO,I2S2ext_SD,,,,,,,DCMI_D9,,EVENTOUT
|
||||
PortI,PI3,,,,TIM8_ETR,,SPI2_MOSI/I2S2_SD,,,,,,,,DCMI_D10,,EVENTOUT
|
||||
PortI,PI4,,,,TIM8_BKIN,,,,,,,,,,DCMI_D5,,EVENTOUT
|
||||
PortI,PI5,,,,TIM8_CH1,,,,,,,,,,DCMI_VSYNC,,EVENTOUT
|
||||
PortI,PI6,,,,TIM8_CH2,,,,,,,,,,DCMI_D6,,EVENTOUT
|
||||
PortI,PI7,,,,TIM8_CH3,,,,,,,,,,DCMI_D7,,EVENTOUT
|
||||
PortI,PI8,,,,,,,,,,,,,,,,EVENTOUT
|
||||
PortI,PI9,,,,,,,,,,CAN1_RX,,,,,,EVENTOUT
|
||||
PortI,PI10,,,,,,,,,,,,ETH_MII_RX_ER,,,,EVENTOUT
|
||||
PortI,PI11,,,,,,,,,,,OTG_HS_ULPI_DIR,,,,,EVENTOUT
|
|
@ -1,34 +0,0 @@
|
||||
// stm32fxx-prefix.c becomes the initial portion of the generated pins file.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stm32f4xx.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
|
||||
#include "pin.h"
|
||||
|
||||
#define AF(af_idx, af_fn, af_unit, af_type, af_ptr) \
|
||||
{ \
|
||||
{ &pin_af_obj_type }, \
|
||||
.idx = (af_idx), \
|
||||
.fn = AF_FN_ ## af_fn, \
|
||||
.unit = (af_unit), \
|
||||
.type = AF_PIN_TYPE_ ## af_fn ## _ ## af_type, \
|
||||
.af_fn = (af_ptr) \
|
||||
}
|
||||
|
||||
#define PIN(p_port, p_pin, p_num_af, p_af) \
|
||||
{ \
|
||||
{ &pin_obj_type }, \
|
||||
.name = #p_port #p_pin, \
|
||||
.port = PORT_ ## p_port, \
|
||||
.pin = (p_pin), \
|
||||
.num_af = (p_num_af), \
|
||||
.pin_mask = (1 << ((p_pin) & 0x0f)), \
|
||||
.gpio = GPIO ## p_port, \
|
||||
.af = p_af, \
|
||||
}
|
@ -1,196 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* cc3000_common.c.c - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup common_api
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
/******************************************************************************
|
||||
*
|
||||
* Include files
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cc3000_common.h"
|
||||
#include "socket.h"
|
||||
#include "wlan.h"
|
||||
#include "evnt_handler.h"
|
||||
#include "ccdebug.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! __error__
|
||||
//!
|
||||
//! @param pcFilename - file name, where error occurred
|
||||
//! @param ulLine - line number, where error occurred
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief stub function for ASSERT macro
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
__error__(char *pcFilename, unsigned long ulLine)
|
||||
{
|
||||
//TODO full up function
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! UINT32_TO_STREAM_f
|
||||
//!
|
||||
//! @param p pointer to the new stream
|
||||
//! @param u32 pointer to the 32 bit
|
||||
//!
|
||||
//! @return pointer to the new stream
|
||||
//!
|
||||
//! @brief This function is used for copying 32 bit to stream
|
||||
//! while converting to little endian format.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
uint8_t* UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32)
|
||||
{
|
||||
*(p)++ = (uint8_t)(u32);
|
||||
*(p)++ = (uint8_t)((u32) >> 8);
|
||||
*(p)++ = (uint8_t)((u32) >> 16);
|
||||
*(p)++ = (uint8_t)((u32) >> 24);
|
||||
return p;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! UINT16_TO_STREAM_f
|
||||
//!
|
||||
//! @param p pointer to the new stream
|
||||
//! @param u32 pointer to the 16 bit
|
||||
//!
|
||||
//! @return pointer to the new stream
|
||||
//!
|
||||
//! @brief This function is used for copying 16 bit to stream
|
||||
//! while converting to little endian format.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16)
|
||||
{
|
||||
*(p)++ = (uint8_t)(u16);
|
||||
*(p)++ = (uint8_t)((u16) >> 8);
|
||||
return p;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! STREAM_TO_UINT16_f
|
||||
//!
|
||||
//! @param p pointer to the stream
|
||||
//! @param offset offset in the stream
|
||||
//!
|
||||
//! @return pointer to the new 16 bit
|
||||
//!
|
||||
//! @brief This function is used for copying received stream to
|
||||
//! 16 bit in little endian format.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
uint16_t STREAM_TO_UINT16_f(char* cp, uint16_t offset)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)cp;
|
||||
/*
|
||||
DEBUGPRINT_F("Stream2u16: ");
|
||||
DEBUGPRINT_HEX(cp[offset+1]);
|
||||
DEBUGPRINT_F(" + ");
|
||||
DEBUGPRINT_HEX(cp[offset]);
|
||||
DEBUGPRINT_F("\n\r");
|
||||
*/
|
||||
|
||||
return (uint16_t)((uint16_t)
|
||||
((uint16_t)(*(p + offset + 1)) << 8) +
|
||||
(uint16_t)(*(p + offset)));
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! STREAM_TO_UINT32_f
|
||||
//!
|
||||
//! @param p pointer to the stream
|
||||
//! @param offset offset in the stream
|
||||
//!
|
||||
//! @return pointer to the new 32 bit
|
||||
//!
|
||||
//! @brief This function is used for copying received stream to
|
||||
//! 32 bit in little endian format.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
uint32_t STREAM_TO_UINT32_f(char * cp, uint16_t offset)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)cp;
|
||||
|
||||
/*
|
||||
DEBUGPRINT_F("\tStream2u32: ");
|
||||
DEBUGPRINT_HEX(cp[offset+3]); DEBUGPRINT_F(" + ");
|
||||
DEBUGPRINT_HEX(cp[offset+2]); DEBUGPRINT_F(" + ");
|
||||
DEBUGPRINT_HEX(cp[offset+1]); DEBUGPRINT_F(" + ");
|
||||
DEBUGPRINT_HEX(cp[offset]);
|
||||
DEBUGPRINT_F("\n\r");
|
||||
*/
|
||||
|
||||
return (uint32_t)((uint32_t)((uint32_t)
|
||||
(*(p + offset + 3)) << 24) + (uint32_t)((uint32_t)
|
||||
(*(p + offset + 2)) << 16) + (uint32_t)((uint32_t)
|
||||
(*(p + offset + 1)) << 8) + (uint32_t)(*(p + offset)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
@ -1,385 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* cc3000_common.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef __COMMON_H__
|
||||
#define __COMMON_H__
|
||||
|
||||
//******************************************************************************
|
||||
// Include files
|
||||
//******************************************************************************
|
||||
//#include <stdlib.h>
|
||||
//#include <errno.h>
|
||||
//#include <stdint.h>
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
// ERROR CODES
|
||||
//*****************************************************************************
|
||||
#define ESUCCESS 0
|
||||
#define EFAIL -1
|
||||
#define EERROR EFAIL
|
||||
|
||||
//*****************************************************************************
|
||||
// COMMON DEFINES
|
||||
//*****************************************************************************
|
||||
#define ERROR_SOCKET_INACTIVE -57
|
||||
|
||||
#define WLAN_ENABLE (1)
|
||||
#define WLAN_DISABLE (0)
|
||||
|
||||
#define MAC_ADDR_LEN (6)
|
||||
|
||||
#define SP_PORTION_SIZE (32)
|
||||
|
||||
// #define CC3000_TINY_DRIVER
|
||||
|
||||
/*Defines for minimal and maximal RX buffer size. This size includes the spi
|
||||
header and hci header.
|
||||
The maximal buffer size derives from:
|
||||
MTU + HCI header + SPI header + sendto() agrs size
|
||||
The minimum buffer size derives from:
|
||||
HCI header + SPI header + max args size
|
||||
|
||||
This buffer is used for receiving events and data.
|
||||
The packet can not be longer than MTU size and CC3000 does not support
|
||||
fragmentation. Note that the same buffer is used for reception of the data
|
||||
and events from CC3000. That is why the minimum is defined.
|
||||
The calculation for the actual size of buffer for reception is:
|
||||
Given the maximal data size MAX_DATA that is expected to be received by
|
||||
application, the required buffer is:
|
||||
Using recv() or recvfrom():
|
||||
|
||||
max(CC3000_MINIMAL_RX_SIZE, MAX_DATA + HEADERS_SIZE_DATA + fromlen
|
||||
+ ucArgsize + 1)
|
||||
|
||||
Using gethostbyname() with minimal buffer size will limit the host name
|
||||
returned to 99 bytes only.
|
||||
The 1 is used for the overrun detection
|
||||
|
||||
Buffer size increased to 130 following the add_profile() with WEP security
|
||||
which requires TX buffer size of 130 bytes:
|
||||
HEADERS_SIZE_EVNT + WLAN_ADD_PROFILE_WEP_PARAM_LEN + MAX SSID LEN + 4 * MAX KEY LEN = 130
|
||||
MAX SSID LEN = 32
|
||||
MAX SSID LEN = 13 (with add_profile only ascii key setting is supported,
|
||||
therfore maximum key size is 13)
|
||||
*/
|
||||
|
||||
#define CC3000_MINIMAL_RX_SIZE (130 + 1)
|
||||
#define CC3000_MAXIMAL_RX_SIZE (1519 + 1)
|
||||
|
||||
/*Defines for minimal and maximal TX buffer size.
|
||||
This buffer is used for sending events and data.
|
||||
The packet can not be longer than MTU size and CC3000 does not support
|
||||
fragmentation. Note that the same buffer is used for transmission of the data
|
||||
and commands. That is why the minimum is defined.
|
||||
The calculation for the actual size of buffer for transmission is:
|
||||
Given the maximal data size MAX_DATA, the required buffer is:
|
||||
Using Sendto():
|
||||
|
||||
max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
|
||||
+ SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
|
||||
|
||||
Using Send():
|
||||
|
||||
max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
|
||||
+ HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
|
||||
|
||||
The 1 is used for the overrun detection */
|
||||
|
||||
#define CC3000_MINIMAL_TX_SIZE (130 + 1)
|
||||
#define CC3000_MAXIMAL_TX_SIZE (1519 + 1)
|
||||
|
||||
//TX and RX buffer sizes, allow to receive and transmit maximum data at length 8.
|
||||
#ifdef CC3000_TINY_DRIVER
|
||||
#define TINY_CC3000_MAXIMAL_RX_SIZE 44
|
||||
#define TINY_CC3000_MAXIMAL_TX_SIZE 59
|
||||
#endif
|
||||
|
||||
/*In order to determine your preferred buffer size,
|
||||
change CC3000_MAXIMAL_RX_SIZE and CC3000_MAXIMAL_TX_SIZE to a value between
|
||||
the minimal and maximal specified above.
|
||||
Note that the buffers are allocated by SPI.
|
||||
In case you change the size of those buffers, you might need also to change
|
||||
the linker file, since for example on MSP430 FRAM devices the buffers are
|
||||
allocated in the FRAM section that is allocated manually and not by IDE.
|
||||
*/
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
|
||||
#define CC3000_RX_BUFFER_SIZE (CC3000_MINIMAL_RX_SIZE)
|
||||
#define CC3000_TX_BUFFER_SIZE (CC3000_MINIMAL_TX_SIZE)
|
||||
|
||||
//if defined TINY DRIVER we use smaller RX and TX buffer in order to minimize RAM consumption
|
||||
#else
|
||||
#define CC3000_RX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_RX_SIZE)
|
||||
#define CC3000_TX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_TX_SIZE)
|
||||
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
// Compound Types
|
||||
//*****************************************************************************
|
||||
#ifdef __AVR__
|
||||
typedef unsigned long time_t; /* KTown: Updated to be compatible with Arduino Time.h */
|
||||
#else
|
||||
typedef long time_t;
|
||||
#endif
|
||||
typedef unsigned long clock_t;
|
||||
typedef long suseconds_t;
|
||||
|
||||
typedef struct timeval timeval;
|
||||
|
||||
struct timeval
|
||||
{
|
||||
time_t tv_sec; /* seconds */
|
||||
suseconds_t tv_usec; /* microseconds */
|
||||
};
|
||||
|
||||
typedef char *(*tFWPatches)(unsigned long *usLength);
|
||||
|
||||
typedef char *(*tDriverPatches)(unsigned long *usLength);
|
||||
|
||||
typedef char *(*tBootLoaderPatches)(unsigned long *usLength);
|
||||
|
||||
typedef void (*tWlanCB)(long event_type, char * data, unsigned char length );
|
||||
|
||||
typedef long (*tWlanReadInteruptPin)(void);
|
||||
|
||||
typedef void (*tWlanInterruptEnable)(void);
|
||||
|
||||
typedef void (*tWlanInterruptDisable)(void);
|
||||
|
||||
typedef void (*tWriteWlanPin)(unsigned char val);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usRxEventOpcode;
|
||||
unsigned short usEventOrDataReceived;
|
||||
unsigned char *pucReceivedData;
|
||||
unsigned char *pucTxCommandBuffer;
|
||||
|
||||
tFWPatches sFWPatches;
|
||||
tDriverPatches sDriverPatches;
|
||||
tBootLoaderPatches sBootLoaderPatches;
|
||||
tWlanCB sWlanCB;
|
||||
tWlanReadInteruptPin ReadWlanInterruptPin;
|
||||
tWlanInterruptEnable WlanInterruptEnable;
|
||||
tWlanInterruptDisable WlanInterruptDisable;
|
||||
tWriteWlanPin WriteWlanPin;
|
||||
|
||||
signed long slTransmitDataError;
|
||||
unsigned short usNumberOfFreeBuffers;
|
||||
unsigned short usSlBufferLength;
|
||||
unsigned short usBufferSize;
|
||||
unsigned short usRxDataPending;
|
||||
|
||||
unsigned long NumberOfSentPackets;
|
||||
unsigned long NumberOfReleasedPackets;
|
||||
|
||||
unsigned char InformHostOnTxComplete;
|
||||
}sSimplLinkInformation;
|
||||
|
||||
extern volatile sSimplLinkInformation tSLInformation;
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Prototypes for the APIs.
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! SimpleLinkWaitEvent
|
||||
//!
|
||||
//! @param usOpcode command operation code
|
||||
//! @param pRetParams command return parameters
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Wait for event, pass it to the hci_event_handler and
|
||||
//! update the event opcode in a global variable.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern void SimpleLinkWaitEvent(unsigned short usOpcode, void *pRetParams);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! SimpleLinkWaitData
|
||||
//!
|
||||
//! @param pBuf data buffer
|
||||
//! @param from from information
|
||||
//! @param fromlen from information length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Wait for data, pass it to the hci_event_handler
|
||||
//! and update in a global variable that there is
|
||||
//! data to read.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern void SimpleLinkWaitData(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! UINT32_TO_STREAM_f
|
||||
//!
|
||||
//! \param p pointer to the new stream
|
||||
//! \param u32 pointer to the 32 bit
|
||||
//!
|
||||
//! \return pointer to the new stream
|
||||
//!
|
||||
//! \brief This function is used for copying 32 bit to stream
|
||||
//! while converting to little endian format.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern uint8_t* UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! UINT16_TO_STREAM_f
|
||||
//!
|
||||
//! \param p pointer to the new stream
|
||||
//! \param u32 pointer to the 16 bit
|
||||
//!
|
||||
//! \return pointer to the new stream
|
||||
//!
|
||||
//! \brief This function is used for copying 16 bit to stream
|
||||
//! while converting to little endian format.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! STREAM_TO_UINT16_f
|
||||
//!
|
||||
//! \param p pointer to the stream
|
||||
//! \param offset offset in the stream
|
||||
//!
|
||||
//! \return pointer to the new 16 bit
|
||||
//!
|
||||
//! \brief This function is used for copying received stream to
|
||||
//! 16 bit in little endian format.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern uint16_t STREAM_TO_UINT16_f(char* p, uint16_t offset);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! STREAM_TO_UINT32_f
|
||||
//!
|
||||
//! \param p pointer to the stream
|
||||
//! \param offset offset in the stream
|
||||
//!
|
||||
//! \return pointer to the new 32 bit
|
||||
//!
|
||||
//! \brief This function is used for copying received stream to
|
||||
//! 32 bit in little endian format.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern uint32_t STREAM_TO_UINT32_f(char* p, uint16_t offset);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! cc3k_int_poll
|
||||
//!
|
||||
//! \brief checks if the interrupt pin is low
|
||||
//! just in case the hardware missed a falling edge
|
||||
//! function is in ccspi.cpp
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern void cc3k_int_poll();
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// COMMON MACROs
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//This macro is used for copying 8 bit to stream while converting to little endian format.
|
||||
#define UINT8_TO_STREAM(_p, _val) {*(_p)++ = (_val);}
|
||||
//This macro is used for copying 16 bit to stream while converting to little endian format.
|
||||
#define UINT16_TO_STREAM(_p, _u16) (UINT16_TO_STREAM_f(_p, _u16))
|
||||
//This macro is used for copying 32 bit to stream while converting to little endian format.
|
||||
#define UINT32_TO_STREAM(_p, _u32) (UINT32_TO_STREAM_f(_p, _u32))
|
||||
//This macro is used for copying a specified value length bits (l) to stream while converting to little endian format.
|
||||
#define ARRAY_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(p)++ = ((uint8_t *) a)[_i];}
|
||||
//This macro is used for copying received stream to 8 bit in little endian format.
|
||||
#define STREAM_TO_UINT8(_p, _offset, _u8) {_u8 = (uint8_t)(*(_p + _offset));}
|
||||
//This macro is used for copying received stream to 16 bit in little endian format.
|
||||
#define STREAM_TO_UINT16(_p, _offset, _u16) {_u16 = STREAM_TO_UINT16_f(_p, _offset);}
|
||||
//This macro is used for copying received stream to 32 bit in little endian format.
|
||||
#define STREAM_TO_UINT32(_p, _offset, _u32) {_u32 = STREAM_TO_UINT32_f(_p, _offset);}
|
||||
#define STREAM_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(a)++= ((uint8_t *) p)[_i];}
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __COMMON_H__
|
@ -1,56 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file Adafruit_CC3000.cpp
|
||||
@author KTOWN (Kevin Townsend for Adafruit Industries)
|
||||
@license BSD (see license.txt)
|
||||
|
||||
This is a library for the Adafruit CC3000 WiFi breakout board
|
||||
This library works with the Adafruit CC3000 breakout
|
||||
----> https://www.adafruit.com/products/1469
|
||||
|
||||
Check out the links above for our tutorials and wiring diagrams
|
||||
These chips use SPI to communicate.
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
@section HISTORY
|
||||
|
||||
v1.0 - Initial release
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
//#include <Arduino.h>
|
||||
|
||||
#ifndef _CC3000_DEBUG
|
||||
#define _CC3000_DEBUG
|
||||
|
||||
#define DEBUG_MODE (0)
|
||||
|
||||
#define PRINT_F(__s) DEBUGPRINT(FLASHIFY(__s))
|
||||
|
||||
#if (DEBUG_MODE != 0)
|
||||
#define DEBUGPRINT_F(__s) DEBUGPRINT(FLASHIFY(__s))
|
||||
#define DEBUGPRINT_DEC(x) printDec(x)
|
||||
#define DEBUGPRINT_DEC16(x) printDec16(x)
|
||||
#define DEBUGPRINT_HEX(x) printHex(x)
|
||||
#define DEBUGPRINT_HEX16(x) printHex16(x)
|
||||
#else
|
||||
#define DEBUGPRINT_F(__s) /* do nothing! */
|
||||
#define DEBUGPRINT_DEC(x)
|
||||
#define DEBUGPRINT_DEC16(x)
|
||||
#define DEBUGPRINT_HEX(x)
|
||||
#define DEBUGPRINT_HEX16(x)
|
||||
#endif
|
||||
|
||||
#if 0 // print debugging info
|
||||
#define DEBUG_PRINT (1)
|
||||
#define DEBUG_printf(args...) printf(args)
|
||||
#else // don't print debugging info
|
||||
#define DEBUG_printf(args...) (void)0
|
||||
#endif
|
||||
|
||||
int printf(const char *fmt, ...);
|
||||
|
||||
#endif
|
737
stm/cc3k/ccspi.c
737
stm/cc3k/ccspi.c
@ -1,737 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* spi.c - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include <string.h> // for memset
|
||||
|
||||
#include "ccspi.h"
|
||||
#include "hci.h"
|
||||
#include "netapp.h"
|
||||
#include "evnt_handler.h"
|
||||
#include "cc3000_common.h"
|
||||
#include "ccdebug.h"
|
||||
#include "pybcc3k.h"
|
||||
|
||||
extern uint8_t g_csPin, g_irqPin, g_vbatPin, g_IRQnum, g_SPIspeed;
|
||||
|
||||
#define READ (3)
|
||||
#define WRITE (1)
|
||||
#define HI(value) (((value) & 0xFF00) >> 8)
|
||||
#define LO(value) ((value) & 0x00FF)
|
||||
#define HEADERS_SIZE_EVNT (SPI_HEADER_SIZE + 5)
|
||||
#define SPI_HEADER_SIZE (5)
|
||||
|
||||
#define eSPI_STATE_POWERUP (0)
|
||||
#define eSPI_STATE_INITIALIZED (1)
|
||||
#define eSPI_STATE_IDLE (2)
|
||||
#define eSPI_STATE_WRITE_IRQ (3)
|
||||
#define eSPI_STATE_WRITE_FIRST_PORTION (4)
|
||||
#define eSPI_STATE_WRITE_EOT (5)
|
||||
#define eSPI_STATE_READ_IRQ (6)
|
||||
#define eSPI_STATE_READ_FIRST_PORTION (7)
|
||||
#define eSPI_STATE_READ_EOT (8)
|
||||
|
||||
// CC3000 chip select
|
||||
#define CC3000_ASSERT_CS() pyb_cc3000_set_cs(0)
|
||||
// CC3000 chip deselect
|
||||
#define CC3000_DEASSERT_CS() pyb_cc3000_set_cs(1)
|
||||
|
||||
/* smartconfig flags (defined in Adafruit_CC3000.cpp) */
|
||||
// extern unsigned long ulSmartConfigFinished, ulCC3000DHCP;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gcSpiHandleRx SPIRxHandler;
|
||||
|
||||
unsigned short usTxPacketLength;
|
||||
unsigned short usRxPacketLength;
|
||||
unsigned long ulSpiState;
|
||||
unsigned char *pTxPacket;
|
||||
unsigned char *pRxPacket;
|
||||
|
||||
} tSpiInformation;
|
||||
|
||||
tSpiInformation sSpiInformation;
|
||||
|
||||
/* Static buffer for 5 bytes of SPI HEADER */
|
||||
unsigned char tSpiReadHeader[] = {READ, 0, 0, 0, 0};
|
||||
|
||||
void SpiWriteDataSynchronous(unsigned char *data, unsigned short size);
|
||||
void SpiWriteAsync(const unsigned char *data, unsigned short size);
|
||||
void SpiPauseSpi(void);
|
||||
void SpiResumeSpi(void);
|
||||
void SSIContReadOperation(void);
|
||||
void cc3k_int_poll(void);
|
||||
|
||||
// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
|
||||
// for the purpose of detection of the overrun. The location of the memory where the magic number
|
||||
// resides shall never be written. In case it is written - the overrun occured and either recevie function
|
||||
// or send function will stuck forever.
|
||||
#define CC3000_BUFFER_MAGIC_NUMBER (0xDE)
|
||||
|
||||
char spi_buffer[CC3000_RX_BUFFER_SIZE];
|
||||
unsigned char wlan_tx_buffer[CC3000_TX_BUFFER_SIZE];
|
||||
|
||||
static volatile char ccspi_is_in_irq = 0;
|
||||
static volatile char ccspi_int_enabled = 0;
|
||||
|
||||
/* Mandatory functions are:
|
||||
- SpiOpen
|
||||
- SpiWrite
|
||||
- SpiRead
|
||||
- SpiClose
|
||||
- SpiResumeSpi
|
||||
- ReadWlanInterruptPin
|
||||
- WlanInterruptEnable
|
||||
- WlanInterruptDisable
|
||||
- WriteWlanPin
|
||||
*/
|
||||
|
||||
void SpiInit(void)
|
||||
{
|
||||
pyb_cc3000_spi_init();
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiClose(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiClose");
|
||||
|
||||
if (sSpiInformation.pRxPacket)
|
||||
{
|
||||
sSpiInformation.pRxPacket = 0;
|
||||
}
|
||||
|
||||
/* Disable Interrupt in GPIOA module... */
|
||||
tSLInformation.WlanInterruptDisable();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiOpen(gcSpiHandleRx pfRxHandler)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiOpen");
|
||||
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_POWERUP;
|
||||
|
||||
memset(spi_buffer, 0, sizeof(spi_buffer));
|
||||
memset(wlan_tx_buffer, 0, sizeof(spi_buffer));
|
||||
|
||||
sSpiInformation.SPIRxHandler = pfRxHandler;
|
||||
sSpiInformation.usTxPacketLength = 0;
|
||||
sSpiInformation.pTxPacket = NULL;
|
||||
sSpiInformation.pRxPacket = (unsigned char *)spi_buffer;
|
||||
sSpiInformation.usRxPacketLength = 0;
|
||||
|
||||
spi_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
|
||||
wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
|
||||
|
||||
/* Enable interrupt on the GPIO pin of WLAN IRQ */
|
||||
tSLInformation.WlanInterruptEnable();
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: Finished SpiOpen\n\r");
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
#if 0
|
||||
int init_spi(void)
|
||||
{
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: init_spi\n\r");
|
||||
|
||||
/* Set POWER_EN pin to output and disable the CC3000 by default */
|
||||
pinMode(g_vbatPin, OUTPUT);
|
||||
digitalWrite(g_vbatPin, 0);
|
||||
delay(500);
|
||||
|
||||
/* Set CS pin to output (don't de-assert yet) */
|
||||
pinMode(g_csPin, OUTPUT);
|
||||
|
||||
/* Set interrupt/gpio pin to input */
|
||||
#if defined(INPUT_PULLUP)
|
||||
pinMode(g_irqPin, INPUT_PULLUP);
|
||||
#else
|
||||
pinMode(g_irqPin, INPUT);
|
||||
digitalWrite(g_irqPin, HIGH); // w/weak pullup
|
||||
#endif
|
||||
|
||||
/* Initialise SPI (Mode 1) */
|
||||
SPI.begin();
|
||||
SPI.setDataMode(SPI_MODE1);
|
||||
SPI.setBitOrder(MSBFIRST);
|
||||
SPI.setClockDivider(g_SPIspeed);
|
||||
|
||||
// Newly-initialized SPI is in the same state that ASSERT_CS will set it
|
||||
// to. Invoke DEASSERT (which also restores SPI registers) so the next
|
||||
// ASSERT call won't clobber the ccspi_old* values -- we need those!
|
||||
CC3000_DEASSERT_CS();
|
||||
|
||||
/* ToDo: Configure IRQ interrupt! */
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: Finished init_spi\n\r");
|
||||
|
||||
return(ESUCCESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiWriteFirst\n\r");
|
||||
|
||||
/* Workaround for the first transaction */
|
||||
CC3000_ASSERT_CS();
|
||||
|
||||
/* delay (stay low) for ~50us */
|
||||
pyb_delay_us(50);
|
||||
|
||||
/* SPI writes first 4 bytes of data */
|
||||
SpiWriteDataSynchronous(ucBuf, 4);
|
||||
|
||||
pyb_delay_us(50);
|
||||
|
||||
SpiWriteDataSynchronous(ucBuf + 4, usLength - 4);
|
||||
|
||||
/* From this point on - operate in a regular manner */
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
|
||||
|
||||
CC3000_DEASSERT_CS();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength)
|
||||
{
|
||||
unsigned char ucPad = 0;
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: SpiWrite\n\r");
|
||||
|
||||
/* Figure out the total length of the packet in order to figure out if there is padding or not */
|
||||
if(!(usLength & 0x0001))
|
||||
{
|
||||
ucPad++;
|
||||
}
|
||||
|
||||
pUserBuffer[0] = WRITE;
|
||||
pUserBuffer[1] = HI(usLength + ucPad);
|
||||
pUserBuffer[2] = LO(usLength + ucPad);
|
||||
pUserBuffer[3] = 0;
|
||||
pUserBuffer[4] = 0;
|
||||
|
||||
usLength += (SPI_HEADER_SIZE + ucPad);
|
||||
|
||||
/* The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
|
||||
* for the purpose of overrun detection. If the magic number is overwritten - buffer overrun
|
||||
* occurred - and we will be stuck here forever! */
|
||||
if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: Error - No magic number found in SpiWrite\n\r");
|
||||
while (1);
|
||||
}
|
||||
|
||||
if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP)
|
||||
{
|
||||
while (sSpiInformation.ulSpiState != eSPI_STATE_INITIALIZED);
|
||||
}
|
||||
|
||||
if (sSpiInformation.ulSpiState == eSPI_STATE_INITIALIZED)
|
||||
{
|
||||
/* This is time for first TX/RX transactions over SPI: the IRQ is down - so need to send read buffer size command */
|
||||
SpiFirstWrite(pUserBuffer, usLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We need to prevent here race that can occur in case two 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 */
|
||||
tSLInformation.WlanInterruptDisable();
|
||||
|
||||
while (sSpiInformation.ulSpiState != eSPI_STATE_IDLE);
|
||||
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_WRITE_IRQ;
|
||||
sSpiInformation.pTxPacket = pUserBuffer;
|
||||
sSpiInformation.usTxPacketLength = usLength;
|
||||
|
||||
/* Assert the CS line and wait till SSI IRQ line is active and then initialize write operation */
|
||||
CC3000_ASSERT_CS();
|
||||
|
||||
/* Re-enable IRQ - if it was not disabled - this is not a problem... */
|
||||
tSLInformation.WlanInterruptEnable();
|
||||
|
||||
/* Check for a missing interrupt between the CS assertion and enabling back the interrupts */
|
||||
if (tSLInformation.ReadWlanInterruptPin() == 0)
|
||||
{
|
||||
SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
|
||||
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
|
||||
|
||||
CC3000_DEASSERT_CS();
|
||||
}
|
||||
}
|
||||
|
||||
/* Due to the fact that we are currently implementing a blocking situation
|
||||
* here we will wait till end of transaction */
|
||||
while (eSPI_STATE_IDLE != sSpiInformation.ulSpiState);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiWriteDataSynchronous(unsigned char *data, unsigned short size)
|
||||
{
|
||||
int bSend = 0, bRecv = 0;
|
||||
while (bSend<size || bRecv<size) {
|
||||
int r = pyb_cc3000_spi_send((bSend<size)?data[bSend]:-1);
|
||||
bSend++;
|
||||
if (bSend>0 && r>=0) bRecv++;
|
||||
}
|
||||
|
||||
pyb_delay_us(10); // because of final clock pulse
|
||||
|
||||
DEBUG_printf("SpiWriteDataSynchronous: data=%p size=%u bSend=%d bRecv=%d [%x %x %x %x]\n", data, size, bSend, bRecv, data[0], data[1], data[2], data[3]);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiReadDataSynchronous(unsigned char *data, unsigned short size)
|
||||
{
|
||||
int bSend = 0, bRecv = 0;
|
||||
while (bSend<size || bRecv<size) {
|
||||
int r = pyb_cc3000_spi_send((bSend<size)?READ:-1);
|
||||
bSend++;
|
||||
if (bSend>0 && r>=0) data[bRecv++] = r;
|
||||
}
|
||||
|
||||
pyb_delay_us(10); // because of final clock pulse
|
||||
|
||||
DEBUG_printf("SpiReadDataSynchronous: data=%p size=%u bSend=%d bRecv=%d [%x %x %x %x]\n", data, size, bSend, bRecv, data[0], data[1], data[2], data[3]);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiReadHeader(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiReadHeader\n\r");
|
||||
|
||||
SpiReadDataSynchronous(sSpiInformation.pRxPacket, HEADERS_SIZE_EVNT);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
long SpiReadDataCont(void)
|
||||
{
|
||||
long data_to_recv;
|
||||
unsigned char *evnt_buff, type;
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: SpiReadDataCont\n\r");
|
||||
|
||||
/* Determine what type of packet we have */
|
||||
evnt_buff = sSpiInformation.pRxPacket;
|
||||
data_to_recv = 0;
|
||||
STREAM_TO_UINT8((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case HCI_TYPE_DATA:
|
||||
{
|
||||
/* We need to read the rest of data.. */
|
||||
STREAM_TO_UINT16((char *)(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)
|
||||
{
|
||||
SpiReadDataSynchronous(evnt_buff + HEADERS_SIZE_EVNT, data_to_recv);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HCI_TYPE_EVNT:
|
||||
{
|
||||
/* 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++;
|
||||
}
|
||||
|
||||
if (data_to_recv)
|
||||
{
|
||||
SpiReadDataSynchronous(evnt_buff + HEADERS_SIZE_EVNT, data_to_recv);
|
||||
}
|
||||
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiPauseSpi(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiPauseSpi\n\r");
|
||||
|
||||
ccspi_int_enabled = 0;
|
||||
pyb_cc3000_pause_spi();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiResumeSpi(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiResumeSpi\n\r");
|
||||
|
||||
ccspi_int_enabled = 1;
|
||||
pyb_cc3000_resume_spi();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiTriggerRxProcessing(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiTriggerRxProcessing\n\r");
|
||||
|
||||
/* Trigger Rx processing */
|
||||
SpiPauseSpi();
|
||||
CC3000_DEASSERT_CS();
|
||||
|
||||
//DEBUGPRINT_F("Magic?\n\r");
|
||||
/* The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
|
||||
* for the purpose of detection of the overrun. If the magic number is overriten - buffer overrun
|
||||
* occurred - and we will stuck here forever! */
|
||||
if (sSpiInformation.pRxPacket[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
|
||||
{
|
||||
/* You've got problems if you're here! */
|
||||
DEBUGPRINT_F("\tCC3000: ERROR - magic number missing!\n\r");
|
||||
while (1);
|
||||
}
|
||||
|
||||
//DEBUGPRINT_F("OK!\n\r");
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
|
||||
sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SSIContReadOperation(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiContReadOperation\n\r");
|
||||
|
||||
/* The header was read - continue with the payload read */
|
||||
if (!SpiReadDataCont())
|
||||
{
|
||||
/* All the data was read - finalize handling by switching to teh task
|
||||
* and calling from task Event Handler */
|
||||
//DEBUGPRINT_F("SPItrig\n\r");
|
||||
SpiTriggerRxProcessing();
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void WriteWlanPin( unsigned char val )
|
||||
{
|
||||
#if 0
|
||||
if (DEBUG_MODE)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: WriteWlanPin - ");
|
||||
DEBUGPRINT_DEC(val);
|
||||
DEBUGPRINT_F("\n\r");
|
||||
delay(1);
|
||||
}
|
||||
if (val)
|
||||
{
|
||||
digitalWrite(g_vbatPin, HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(g_vbatPin, LOW);
|
||||
}
|
||||
#endif
|
||||
pyb_cc3000_set_en(val == WLAN_ENABLE);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
long ReadWlanInterruptPin(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: ReadWlanInterruptPin - ");
|
||||
DEBUGPRINT_DEC(digitalRead(g_irqPin));
|
||||
DEBUGPRINT_F("\n\r");
|
||||
|
||||
return pyb_cc3000_get_irq();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void WlanInterruptEnable()
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: WlanInterruptEnable.\n\r");
|
||||
// delay(100);
|
||||
ccspi_int_enabled = 1;
|
||||
pyb_cc3000_enable_irq();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void WlanInterruptDisable()
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: WlanInterruptDisable\n\r");
|
||||
ccspi_int_enabled = 0;
|
||||
pyb_cc3000_disable_irq();
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! sendDriverPatch
|
||||
//!
|
||||
//! @param pointer to the length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief The function returns a pointer to the driver patch:
|
||||
//! since there is no patch in the host - it returns 0
|
||||
//
|
||||
//*****************************************************************************
|
||||
char *sendDriverPatch(unsigned long *Length) {
|
||||
*Length = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! sendBootLoaderPatch
|
||||
//!
|
||||
//! @param pointer to the length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief The function returns a pointer to the boot loader patch:
|
||||
//! since there is no patch in the host - it returns 0
|
||||
//
|
||||
//*****************************************************************************
|
||||
char *sendBootLoaderPatch(unsigned long *Length) {
|
||||
*Length = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! sendWLFWPatch
|
||||
//!
|
||||
//! @param pointer to the length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief The function returns a pointer to the FW patch:
|
||||
//! since there is no patch in the host - it returns 0
|
||||
//
|
||||
//*****************************************************************************
|
||||
char *sendWLFWPatch(unsigned long *Length) {
|
||||
*Length = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
void SpiIntGPIOHandler(void)
|
||||
{
|
||||
DEBUG_printf("SpiIntGPIOHandler\n");
|
||||
|
||||
ccspi_is_in_irq = 1;
|
||||
|
||||
if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP)
|
||||
{
|
||||
//This means IRQ line was low call a callback of HCI Layer to inform
|
||||
//on event
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED;
|
||||
}
|
||||
else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE)
|
||||
{
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ;
|
||||
|
||||
/* IRQ line goes down - we are start reception */
|
||||
CC3000_ASSERT_CS();
|
||||
|
||||
// Wait for TX/RX Compete which will come as DMA interrupt
|
||||
SpiReadHeader();
|
||||
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
|
||||
|
||||
SSIContReadOperation();
|
||||
}
|
||||
else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ)
|
||||
{
|
||||
SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
|
||||
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
|
||||
|
||||
CC3000_DEASSERT_CS();
|
||||
}
|
||||
ccspi_is_in_irq = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void SPI_IRQ(void)
|
||||
{
|
||||
ccspi_is_in_irq = 1;
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: Entering SPI_IRQ\n\r");
|
||||
|
||||
if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP)
|
||||
{
|
||||
/* IRQ line was low ... perform a callback on the HCI Layer */
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED;
|
||||
}
|
||||
else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE)
|
||||
{
|
||||
//DEBUGPRINT_F("IDLE\n\r");
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ;
|
||||
/* IRQ line goes down - start reception */
|
||||
|
||||
CC3000_ASSERT_CS();
|
||||
|
||||
// Wait for TX/RX Compete which will come as DMA interrupt
|
||||
SpiReadHeader();
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
|
||||
//DEBUGPRINT_F("SSICont\n\r");
|
||||
SSIContReadOperation();
|
||||
}
|
||||
else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ)
|
||||
{
|
||||
SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
|
||||
CC3000_DEASSERT_CS();
|
||||
}
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: Leaving SPI_IRQ\n\r");
|
||||
|
||||
ccspi_is_in_irq = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! cc3k_int_poll
|
||||
//!
|
||||
//! \brief checks if the interrupt pin is low
|
||||
//! just in case the hardware missed a falling edge
|
||||
//! function is in ccspi.cpp
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
void cc3k_int_poll()
|
||||
{
|
||||
if (pyb_cc3000_get_irq() == 0 && ccspi_is_in_irq == 0 && ccspi_int_enabled != 0) {
|
||||
SpiIntGPIOHandler();
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* spi.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef __SPI_H__
|
||||
#define __SPI_H__
|
||||
|
||||
//#include <string.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <stdio.h>
|
||||
|
||||
//#include "wlan.h"
|
||||
|
||||
typedef void (*gcSpiHandleRx)(void *p);
|
||||
typedef void (*gcSpiHandleTx)(void);
|
||||
|
||||
extern unsigned char wlan_tx_buffer[];
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Prototypes for the APIs.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void SpiInit(void);
|
||||
extern void SpiOpen(gcSpiHandleRx pfRxHandler);
|
||||
extern void SpiClose(void);
|
||||
extern long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength);
|
||||
extern void SpiResumeSpi(void);
|
||||
extern void SpiCleanGPIOISR(void);
|
||||
extern long TXBufferIsEmpty(void);
|
||||
extern long RXBufferIsEmpty(void);
|
||||
extern void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length);
|
||||
extern void WriteWlanPin( unsigned char val );
|
||||
extern long ReadWlanInterruptPin(void);
|
||||
extern void WlanInterruptEnable();
|
||||
extern void WlanInterruptDisable();
|
||||
extern char *sendDriverPatch(unsigned long *Length);
|
||||
extern char *sendBootLoaderPatch(unsigned long *Length);
|
||||
extern char *sendWLFWPatch(unsigned long *Length);
|
||||
extern void SpiIntGPIOHandler(void);
|
||||
|
||||
#endif
|
||||
|
@ -1,873 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* evnt_handler.c - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup evnt_handler_api
|
||||
//! @{
|
||||
//
|
||||
//******************************************************************************
|
||||
|
||||
//******************************************************************************
|
||||
// INCLUDE FILES
|
||||
//******************************************************************************
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cc3000_common.h"
|
||||
#include "string.h"
|
||||
#include "hci.h"
|
||||
#include "evnt_handler.h"
|
||||
#include "wlan.h"
|
||||
#include "socket.h"
|
||||
#include "netapp.h"
|
||||
#include "ccspi.h"
|
||||
#include "ccdebug.h"
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// COMMON DEFINES
|
||||
//*****************************************************************************
|
||||
|
||||
#define FLOW_CONTROL_EVENT_HANDLE_OFFSET (0)
|
||||
#define FLOW_CONTROL_EVENT_BLOCK_MODE_OFFSET (1)
|
||||
#define FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET (2)
|
||||
#define FLOW_CONTROL_EVENT_SIZE (4)
|
||||
|
||||
#define BSD_RSP_PARAMS_SOCKET_OFFSET (0)
|
||||
#define BSD_RSP_PARAMS_STATUS_OFFSET (4)
|
||||
|
||||
#define GET_HOST_BY_NAME_RETVAL_OFFSET (0)
|
||||
#define GET_HOST_BY_NAME_ADDR_OFFSET (4)
|
||||
|
||||
#define ACCEPT_SD_OFFSET (0)
|
||||
#define ACCEPT_RETURN_STATUS_OFFSET (4)
|
||||
#define ACCEPT_ADDRESS__OFFSET (8)
|
||||
|
||||
#define SL_RECEIVE_SD_OFFSET (0)
|
||||
#define SL_RECEIVE_NUM_BYTES_OFFSET (4)
|
||||
#define SL_RECEIVE__FLAGS__OFFSET (8)
|
||||
|
||||
|
||||
#define SELECT_STATUS_OFFSET (0)
|
||||
#define SELECT_READFD_OFFSET (4)
|
||||
#define SELECT_WRITEFD_OFFSET (8)
|
||||
#define SELECT_EXFD_OFFSET (12)
|
||||
|
||||
|
||||
#define NETAPP_IPCONFIG_IP_OFFSET (0)
|
||||
#define NETAPP_IPCONFIG_SUBNET_OFFSET (4)
|
||||
#define NETAPP_IPCONFIG_GW_OFFSET (8)
|
||||
#define NETAPP_IPCONFIG_DHCP_OFFSET (12)
|
||||
#define NETAPP_IPCONFIG_DNS_OFFSET (16)
|
||||
#define NETAPP_IPCONFIG_MAC_OFFSET (20)
|
||||
#define NETAPP_IPCONFIG_SSID_OFFSET (26)
|
||||
|
||||
#define NETAPP_IPCONFIG_IP_LENGTH (4)
|
||||
#define NETAPP_IPCONFIG_MAC_LENGTH (6)
|
||||
#define NETAPP_IPCONFIG_SSID_LENGTH (32)
|
||||
|
||||
|
||||
#define NETAPP_PING_PACKETS_SENT_OFFSET (0)
|
||||
#define NETAPP_PING_PACKETS_RCVD_OFFSET (4)
|
||||
#define NETAPP_PING_MIN_RTT_OFFSET (8)
|
||||
#define NETAPP_PING_MAX_RTT_OFFSET (12)
|
||||
#define NETAPP_PING_AVG_RTT_OFFSET (16)
|
||||
|
||||
#define GET_SCAN_RESULTS_TABlE_COUNT_OFFSET (0)
|
||||
#define GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET (4)
|
||||
#define GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET (8)
|
||||
#define GET_SCAN_RESULTS_FRAME_TIME_OFFSET (10)
|
||||
#define GET_SCAN_RESULTS_SSID_MAC_LENGTH (38)
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// GLOBAL VARAIABLES
|
||||
//*****************************************************************************
|
||||
|
||||
unsigned long socket_active_status = SOCKET_STATUS_INIT_VAL;
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Prototypes for the static functions
|
||||
//*****************************************************************************
|
||||
|
||||
static long hci_event_unsol_flowcontrol_handler(char *pEvent);
|
||||
|
||||
static void update_socket_active_status(char *resp_params);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_unsol_handle_patch_request
|
||||
//!
|
||||
//! @param event_hdr event header
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Handle unsolicited event from type patch request
|
||||
//
|
||||
//*****************************************************************************
|
||||
void hci_unsol_handle_patch_request(char *event_hdr)
|
||||
{
|
||||
char *params = (char *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
|
||||
unsigned long ucLength = 0;
|
||||
char *patch;
|
||||
|
||||
switch (*params)
|
||||
{
|
||||
case HCI_EVENT_PATCHES_DRV_REQ:
|
||||
|
||||
if (tSLInformation.sDriverPatches)
|
||||
{
|
||||
patch = tSLInformation.sDriverPatches(&ucLength);
|
||||
|
||||
if (patch)
|
||||
{
|
||||
hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ,
|
||||
tSLInformation.pucTxCommandBuffer, patch, ucLength);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Send 0 length Patches response event
|
||||
hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ,
|
||||
tSLInformation.pucTxCommandBuffer, 0, 0);
|
||||
break;
|
||||
|
||||
case HCI_EVENT_PATCHES_FW_REQ:
|
||||
|
||||
if (tSLInformation.sFWPatches)
|
||||
{
|
||||
patch = tSLInformation.sFWPatches(&ucLength);
|
||||
|
||||
// Build and send a patch
|
||||
if (patch)
|
||||
{
|
||||
hci_patch_send(HCI_EVENT_PATCHES_FW_REQ,
|
||||
tSLInformation.pucTxCommandBuffer, patch, ucLength);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Send 0 length Patches response event
|
||||
hci_patch_send(HCI_EVENT_PATCHES_FW_REQ,
|
||||
tSLInformation.pucTxCommandBuffer, 0, 0);
|
||||
break;
|
||||
|
||||
case HCI_EVENT_PATCHES_BOOTLOAD_REQ:
|
||||
|
||||
if (tSLInformation.sBootLoaderPatches)
|
||||
{
|
||||
patch = tSLInformation.sBootLoaderPatches(&ucLength);
|
||||
|
||||
if (patch)
|
||||
{
|
||||
hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ,
|
||||
tSLInformation.pucTxCommandBuffer, patch, ucLength);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Send 0 length Patches response event
|
||||
hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ,
|
||||
tSLInformation.pucTxCommandBuffer, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_event_handler
|
||||
//!
|
||||
//! @param pRetParams incoming data buffer
|
||||
//! @param from from information (in case of data received)
|
||||
//! @param fromlen from information length (in case of data received)
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Parse the incoming events packets and issues corresponding
|
||||
//! event handler from global array of handlers pointers
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
unsigned char *
|
||||
hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
|
||||
{
|
||||
unsigned char *pucReceivedData, ucArgsize;
|
||||
unsigned short usLength;
|
||||
unsigned char *pucReceivedParams;
|
||||
unsigned short usReceivedEventOpcode = 0;
|
||||
unsigned long retValue32;
|
||||
unsigned char * RecvParams;
|
||||
unsigned char *RetParams;
|
||||
|
||||
while (1)
|
||||
{
|
||||
cc3k_int_poll();
|
||||
|
||||
if (tSLInformation.usEventOrDataReceived != 0)
|
||||
{
|
||||
|
||||
pucReceivedData = (tSLInformation.pucReceivedData);
|
||||
|
||||
if (*pucReceivedData == HCI_TYPE_EVNT)
|
||||
{
|
||||
// Event Received
|
||||
STREAM_TO_UINT16((char *)pucReceivedData,
|
||||
HCI_EVENT_OPCODE_OFFSET,
|
||||
usReceivedEventOpcode);
|
||||
pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE;
|
||||
RecvParams = pucReceivedParams;
|
||||
RetParams = (unsigned char *)pRetParams;
|
||||
|
||||
// In case unsolicited event received - here the handling finished
|
||||
if (hci_unsol_event_handler((char *)pucReceivedData) == 0)
|
||||
{
|
||||
STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength);
|
||||
|
||||
switch(usReceivedEventOpcode)
|
||||
{
|
||||
case HCI_CMND_READ_BUFFER_SIZE:
|
||||
{
|
||||
STREAM_TO_UINT8((char *)pucReceivedParams, 0,
|
||||
tSLInformation.usNumberOfFreeBuffers);
|
||||
STREAM_TO_UINT16((char *)pucReceivedParams, 1,
|
||||
tSLInformation.usSlBufferLength);
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_CMND_WLAN_CONFIGURE_PATCH:
|
||||
case HCI_NETAPP_DHCP:
|
||||
case HCI_NETAPP_PING_SEND:
|
||||
case HCI_NETAPP_PING_STOP:
|
||||
case HCI_NETAPP_ARP_FLUSH:
|
||||
case HCI_NETAPP_SET_DEBUG_LEVEL:
|
||||
case HCI_NETAPP_SET_TIMERS:
|
||||
case HCI_EVNT_NVMEM_READ:
|
||||
case HCI_EVNT_NVMEM_CREATE_ENTRY:
|
||||
case HCI_CMND_NVMEM_WRITE_PATCH:
|
||||
case HCI_NETAPP_PING_REPORT:
|
||||
case HCI_EVNT_MDNS_ADVERTISE:
|
||||
|
||||
STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET
|
||||
,*(unsigned char *)pRetParams);
|
||||
break;
|
||||
|
||||
case HCI_CMND_SETSOCKOPT:
|
||||
case HCI_CMND_WLAN_CONNECT:
|
||||
case HCI_CMND_WLAN_IOCTL_STATUSGET:
|
||||
case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
|
||||
case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
|
||||
case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
|
||||
case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
|
||||
case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
|
||||
case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
|
||||
case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
|
||||
case HCI_CMND_EVENT_MASK:
|
||||
case HCI_EVNT_WLAN_DISCONNECT:
|
||||
case HCI_EVNT_SOCKET:
|
||||
case HCI_EVNT_BIND:
|
||||
case HCI_CMND_LISTEN:
|
||||
case HCI_EVNT_CLOSE_SOCKET:
|
||||
case HCI_EVNT_CONNECT:
|
||||
case HCI_EVNT_NVMEM_WRITE:
|
||||
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,0
|
||||
,*(unsigned long *)pRetParams);
|
||||
break;
|
||||
|
||||
case HCI_EVNT_READ_SP_VERSION:
|
||||
|
||||
STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET
|
||||
,*(unsigned char *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 1;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32);
|
||||
UINT32_TO_STREAM((unsigned char *)pRetParams, retValue32);
|
||||
break;
|
||||
|
||||
case HCI_EVNT_BSD_GETHOSTBYNAME:
|
||||
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams
|
||||
,GET_HOST_BY_NAME_RETVAL_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams
|
||||
,GET_HOST_BY_NAME_ADDR_OFFSET,*(unsigned long *)pRetParams);
|
||||
break;
|
||||
|
||||
case HCI_EVNT_ACCEPT:
|
||||
{
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_SD_OFFSET
|
||||
,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams
|
||||
,ACCEPT_RETURN_STATUS_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
|
||||
//This argument returns in network order
|
||||
memcpy((unsigned char *)pRetParams,
|
||||
pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));
|
||||
break;
|
||||
}
|
||||
|
||||
case HCI_EVNT_RECV:
|
||||
case HCI_EVNT_RECVFROM:
|
||||
{
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams);
|
||||
//tBsdReadReturnParams *tread = (tBsdReadReturnParams *)pRetParams; // unused
|
||||
if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE)
|
||||
{
|
||||
set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case HCI_EVNT_SEND:
|
||||
case HCI_EVNT_SENDTO:
|
||||
{
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case HCI_EVNT_SELECT:
|
||||
{
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_STATUS_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_READFD_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_EXFD_OFFSET,*(unsigned long *)pRetParams);
|
||||
break;
|
||||
}
|
||||
|
||||
case HCI_CMND_GETSOCKOPT:
|
||||
|
||||
STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus);
|
||||
//This argument returns in network order
|
||||
memcpy((unsigned char *)pRetParams, pucReceivedParams, 4);
|
||||
break;
|
||||
|
||||
case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
|
||||
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 2;
|
||||
STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 2;
|
||||
memcpy((unsigned char *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH);
|
||||
break;
|
||||
|
||||
case HCI_CMND_SIMPLE_LINK_START:
|
||||
break;
|
||||
|
||||
case HCI_NETAPP_IPCONFIG:
|
||||
|
||||
//Read IP address
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
RecvParams += 4;
|
||||
|
||||
//Read subnet
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
RecvParams += 4;
|
||||
|
||||
//Read default GW
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
RecvParams += 4;
|
||||
|
||||
//Read DHCP server
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
RecvParams += 4;
|
||||
|
||||
//Read DNS server
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
RecvParams += 4;
|
||||
|
||||
//Read Mac address
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH);
|
||||
RecvParams += 6;
|
||||
|
||||
//Read SSID
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode)
|
||||
{
|
||||
tSLInformation.usRxEventOpcode = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pucReceivedParams = pucReceivedData;
|
||||
STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize);
|
||||
|
||||
STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength);
|
||||
|
||||
// Data received: note that the only case where from and from length
|
||||
// are not null is in recv from, so fill the args accordingly
|
||||
if (from)
|
||||
{
|
||||
STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen);
|
||||
memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
|
||||
}
|
||||
|
||||
memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize,
|
||||
usLength - ucArgsize);
|
||||
|
||||
tSLInformation.usRxDataPending = 0;
|
||||
}
|
||||
|
||||
tSLInformation.usEventOrDataReceived = 0;
|
||||
|
||||
SpiResumeSpi();
|
||||
|
||||
// Since we are going to TX - we need to handle this event after the
|
||||
// ResumeSPi since we need interrupts
|
||||
if ((*pucReceivedData == HCI_TYPE_EVNT) &&
|
||||
(usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ))
|
||||
{
|
||||
hci_unsol_handle_patch_request((char *)pucReceivedData);
|
||||
}
|
||||
|
||||
if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_unsol_event_handler
|
||||
//!
|
||||
//! @param event_hdr event header
|
||||
//!
|
||||
//! @return 1 if event supported and handled
|
||||
//! 0 if event is not supported
|
||||
//!
|
||||
//! @brief Handle unsolicited events
|
||||
//
|
||||
//*****************************************************************************
|
||||
long
|
||||
hci_unsol_event_handler(char *event_hdr)
|
||||
{
|
||||
char * data = NULL;
|
||||
long event_type;
|
||||
unsigned long NumberOfReleasedPackets;
|
||||
unsigned long NumberOfSentPackets;
|
||||
|
||||
STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type);
|
||||
|
||||
DEBUGPRINT_F("\tHCI_UNSOL_EVT: ");
|
||||
DEBUGPRINT_HEX16(event_type);
|
||||
|
||||
if (event_type & HCI_EVNT_UNSOL_BASE)
|
||||
{
|
||||
switch(event_type)
|
||||
{
|
||||
|
||||
case HCI_EVNT_DATA_UNSOL_FREE_BUFF:
|
||||
{
|
||||
hci_event_unsol_flowcontrol_handler(event_hdr);
|
||||
|
||||
NumberOfReleasedPackets = tSLInformation.NumberOfReleasedPackets;
|
||||
NumberOfSentPackets = tSLInformation.NumberOfSentPackets;
|
||||
|
||||
if (NumberOfReleasedPackets == NumberOfSentPackets)
|
||||
{
|
||||
if (tSLInformation.InformHostOnTxComplete)
|
||||
{
|
||||
tSLInformation.sWlanCB(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(event_type & HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
{
|
||||
switch(event_type)
|
||||
{
|
||||
case HCI_EVNT_WLAN_KEEPALIVE:
|
||||
case HCI_EVNT_WLAN_UNSOL_CONNECT:
|
||||
case HCI_EVNT_WLAN_UNSOL_DISCONNECT:
|
||||
case HCI_EVNT_WLAN_UNSOL_INIT:
|
||||
case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE:
|
||||
|
||||
if( tSLInformation.sWlanCB )
|
||||
{
|
||||
tSLInformation.sWlanCB(event_type, 0, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_EVNT_WLAN_UNSOL_DHCP:
|
||||
{
|
||||
unsigned char params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status
|
||||
unsigned char *recParams = params;
|
||||
|
||||
data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
|
||||
|
||||
//Read IP address
|
||||
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
data += 4;
|
||||
//Read subnet
|
||||
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
data += 4;
|
||||
//Read default GW
|
||||
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
data += 4;
|
||||
//Read DHCP server
|
||||
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
data += 4;
|
||||
//Read DNS server
|
||||
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
// read the status
|
||||
STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams);
|
||||
|
||||
|
||||
if( tSLInformation.sWlanCB )
|
||||
{
|
||||
tSLInformation.sWlanCB(event_type, (char *)params, sizeof(params));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_EVNT_WLAN_ASYNC_PING_REPORT:
|
||||
{
|
||||
netapp_pingreport_args_t params;
|
||||
data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
|
||||
STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent);
|
||||
STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received);
|
||||
STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time);
|
||||
STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time);
|
||||
STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time);
|
||||
|
||||
if( tSLInformation.sWlanCB )
|
||||
{
|
||||
tSLInformation.sWlanCB(event_type, (char *)¶ms, sizeof(params));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
|
||||
{
|
||||
DEBUGPRINT_F("\tTCP Close Wait\n\r");
|
||||
uint8_t socketnum;
|
||||
data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
|
||||
/*
|
||||
printHex(data[0]); PRINT_F("\t");
|
||||
printHex(data[1]); PRINT_F("\t");
|
||||
printHex(data[2]); PRINT_F("\t");
|
||||
printHex(data[3]); PRINT_F("\t");
|
||||
printHex(data[4]); PRINT_F("\t");
|
||||
printHex(data[5]); PRINT_F("\t");
|
||||
*/
|
||||
socketnum = data[0];
|
||||
//STREAM_TO_UINT16(data, 0, socketnum);
|
||||
if( tSLInformation.sWlanCB )
|
||||
{
|
||||
tSLInformation.sWlanCB(event_type, (char *)&socketnum, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//'default' case which means "event not supported"
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO)
|
||||
|| (event_type == HCI_EVNT_WRITE))
|
||||
{
|
||||
char *pArg;
|
||||
long status;
|
||||
|
||||
DEBUGPRINT_F("\tSEND event response\n\r");
|
||||
|
||||
pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr);
|
||||
STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status);
|
||||
|
||||
if (ERROR_SOCKET_INACTIVE == status)
|
||||
{
|
||||
// The only synchronous event that can come from SL device in form of
|
||||
// command complete is "Command Complete" on data sent, in case SL device
|
||||
// was unable to transmit
|
||||
STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, tSLInformation.slTransmitDataError);
|
||||
update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));
|
||||
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_unsolicited_event_handler
|
||||
//!
|
||||
//! @param None
|
||||
//!
|
||||
//! @return ESUCCESS if successful, EFAIL if an error occurred
|
||||
//!
|
||||
//! @brief Parse the incoming unsolicited event packets and issues
|
||||
//! corresponding event handler.
|
||||
//
|
||||
//*****************************************************************************
|
||||
long
|
||||
hci_unsolicited_event_handler(void)
|
||||
{
|
||||
unsigned long res = 0;
|
||||
unsigned char *pucReceivedData;
|
||||
|
||||
if (tSLInformation.usEventOrDataReceived != 0)
|
||||
{
|
||||
pucReceivedData = (tSLInformation.pucReceivedData);
|
||||
|
||||
if (*pucReceivedData == HCI_TYPE_EVNT)
|
||||
{
|
||||
|
||||
// In case unsolicited event received - here the handling finished
|
||||
if (hci_unsol_event_handler((char *)pucReceivedData) == 1)
|
||||
{
|
||||
|
||||
// There was an unsolicited event received - we can release the buffer
|
||||
// and clean the event received
|
||||
tSLInformation.usEventOrDataReceived = 0;
|
||||
|
||||
res = 1;
|
||||
SpiResumeSpi();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! set_socket_active_status
|
||||
//!
|
||||
//! @param Sd
|
||||
//! @param Status
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Check if the socket ID and status are valid and set
|
||||
//! accordingly the global socket status
|
||||
//
|
||||
//*****************************************************************************
|
||||
void set_socket_active_status(long Sd, long Status)
|
||||
{
|
||||
if(M_IS_VALID_SD(Sd) && M_IS_VALID_STATUS(Status))
|
||||
{
|
||||
socket_active_status &= ~(1 << Sd); /* clean socket's mask */
|
||||
socket_active_status |= (Status << Sd); /* set new socket's mask */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_event_unsol_flowcontrol_handler
|
||||
//!
|
||||
//! @param pEvent pointer to the string contains parameters for IPERF
|
||||
//! @return ESUCCESS if successful, EFAIL if an error occurred
|
||||
//!
|
||||
//! @brief Called in case unsolicited event from type
|
||||
//! HCI_EVNT_DATA_UNSOL_FREE_BUFF has received.
|
||||
//! Keep track on the number of packets transmitted and update the
|
||||
//! number of free buffer in the SL device.
|
||||
//
|
||||
//*****************************************************************************
|
||||
long
|
||||
hci_event_unsol_flowcontrol_handler(char *pEvent)
|
||||
{
|
||||
|
||||
long temp, value;
|
||||
unsigned short i;
|
||||
unsigned short pusNumberOfHandles=0;
|
||||
char *pReadPayload;
|
||||
|
||||
STREAM_TO_UINT16((char *)pEvent,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles);
|
||||
pReadPayload = ((char *)pEvent +
|
||||
HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles));
|
||||
temp = 0;
|
||||
|
||||
for(i = 0; i < pusNumberOfHandles ; i++)
|
||||
{
|
||||
STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value);
|
||||
temp += value;
|
||||
pReadPayload += FLOW_CONTROL_EVENT_SIZE;
|
||||
}
|
||||
|
||||
tSLInformation.usNumberOfFreeBuffers += temp;
|
||||
tSLInformation.NumberOfReleasedPackets += temp;
|
||||
|
||||
return(ESUCCESS);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! get_socket_active_status
|
||||
//!
|
||||
//! @param Sd Socket IS
|
||||
//! @return Current status of the socket.
|
||||
//!
|
||||
//! @brief Retrieve socket status
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
long
|
||||
get_socket_active_status(long Sd)
|
||||
{
|
||||
if(M_IS_VALID_SD(Sd))
|
||||
{
|
||||
return (socket_active_status & (1 << Sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE;
|
||||
}
|
||||
return SOCKET_STATUS_INACTIVE;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! update_socket_active_status
|
||||
//!
|
||||
//! @param resp_params Socket IS
|
||||
//! @return Current status of the socket.
|
||||
//!
|
||||
//! @brief Retrieve socket status
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
update_socket_active_status(char *resp_params)
|
||||
{
|
||||
long status, sd;
|
||||
|
||||
STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd);
|
||||
STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status);
|
||||
|
||||
if(ERROR_SOCKET_INACTIVE == status)
|
||||
{
|
||||
set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! SimpleLinkWaitEvent
|
||||
//!
|
||||
//! @param usOpcode command operation code
|
||||
//! @param pRetParams command return parameters
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Wait for event, pass it to the hci_event_handler and
|
||||
//! update the event opcode in a global variable.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
void
|
||||
SimpleLinkWaitEvent(unsigned short usOpcode, void *pRetParams)
|
||||
{
|
||||
// In the blocking implementation the control to caller will be returned only
|
||||
// after the end of current transaction
|
||||
tSLInformation.usRxEventOpcode = usOpcode;
|
||||
hci_event_handler(pRetParams, 0, 0);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! SimpleLinkWaitData
|
||||
//!
|
||||
//! @param pBuf data buffer
|
||||
//! @param from from information
|
||||
//! @param fromlen from information length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Wait for data, pass it to the hci_event_handler
|
||||
//! and update in a global variable that there is
|
||||
//! data to read.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
void
|
||||
SimpleLinkWaitData(unsigned char *pBuf, unsigned char *from,
|
||||
unsigned char *fromlen)
|
||||
{
|
||||
// In the blocking implementation the control to caller will be returned only
|
||||
// after the end of current transaction, i.e. only after data will be received
|
||||
tSLInformation.usRxDataPending = 1;
|
||||
hci_event_handler(pBuf, from, fromlen);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
@ -1,175 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* evnt_handler.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef __EVENT_HANDLER_H__
|
||||
#define __EVENT_HANDLER_H__
|
||||
|
||||
#include "hci.h"
|
||||
#include "socket.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Prototypes for the APIs.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_event_handler
|
||||
//!
|
||||
//! @param pRetParams incoming data buffer
|
||||
//! @param from from information (in case of data received)
|
||||
//! @param fromlen from information length (in case of data received)
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Parse the incoming events packets and issues corresponding
|
||||
//! event handler from global array of handlers pointers
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern unsigned char *hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_unsol_event_handler
|
||||
//!
|
||||
//! @param event_hdr event header
|
||||
//!
|
||||
//! @return 1 if event supported and handled
|
||||
//! 0 if event is not supported
|
||||
//!
|
||||
//! @brief Handle unsolicited events
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long hci_unsol_event_handler(char *event_hdr);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_unsolicited_event_handler
|
||||
//!
|
||||
//! @param None
|
||||
//!
|
||||
//! @return ESUCCESS if successful, EFAIL if an error occurred
|
||||
//!
|
||||
//! @brief Parse the incoming unsolicited event packets and issues
|
||||
//! corresponding event handler.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long hci_unsolicited_event_handler(void);
|
||||
|
||||
#define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((char *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE)
|
||||
|
||||
#define SOCKET_STATUS_ACTIVE 0
|
||||
#define SOCKET_STATUS_INACTIVE 1
|
||||
/* Init socket_active_status = 'all ones': init all sockets with SOCKET_STATUS_INACTIVE.
|
||||
Will be changed by 'set_socket_active_status' upon 'connect' and 'accept' calls */
|
||||
#define SOCKET_STATUS_INIT_VAL 0xFFFF
|
||||
#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7))
|
||||
#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE))
|
||||
|
||||
extern unsigned long socket_active_status;
|
||||
|
||||
extern void set_socket_active_status(long Sd, long Status);
|
||||
extern long get_socket_active_status(long Sd);
|
||||
|
||||
typedef struct _bsd_accept_return_t
|
||||
{
|
||||
long iSocketDescriptor;
|
||||
long iStatus;
|
||||
sockaddr tSocketAddress;
|
||||
|
||||
} tBsdReturnParams;
|
||||
|
||||
|
||||
typedef struct _bsd_read_return_t
|
||||
{
|
||||
long iSocketDescriptor;
|
||||
long iNumberOfBytes;
|
||||
unsigned long uiFlags;
|
||||
} tBsdReadReturnParams;
|
||||
|
||||
#define BSD_RECV_FROM_FROMLEN_OFFSET (4)
|
||||
#define BSD_RECV_FROM_FROM_OFFSET (16)
|
||||
|
||||
|
||||
typedef struct _bsd_select_return_t
|
||||
{
|
||||
long iStatus;
|
||||
unsigned long uiRdfd;
|
||||
unsigned long uiWrfd;
|
||||
unsigned long uiExfd;
|
||||
} tBsdSelectRecvParams;
|
||||
|
||||
|
||||
typedef struct _bsd_getsockopt_return_t
|
||||
{
|
||||
unsigned char ucOptValue[4];
|
||||
char iStatus;
|
||||
} tBsdGetSockOptReturnParams;
|
||||
|
||||
typedef struct _bsd_gethostbyname_return_t
|
||||
{
|
||||
long retVal;
|
||||
long outputAddress;
|
||||
} tBsdGethostbynameParams;
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __EVENT_HANDLER_H__
|
||||
|
242
stm/cc3k/hci.c
242
stm/cc3k/hci.c
@ -1,242 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* hci.c - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup hci_app
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h> // for memcpy
|
||||
|
||||
#include "cc3000_common.h"
|
||||
#include "hci.h"
|
||||
#include "ccspi.h"
|
||||
#include "evnt_handler.h"
|
||||
#include "wlan.h"
|
||||
|
||||
#define SL_PATCH_PORTION_SIZE (1000)
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_command_send
|
||||
//!
|
||||
//! @param usOpcode command operation code
|
||||
//! @param pucBuff pointer to the command's arguments buffer
|
||||
//! @param ucArgsLength length of the arguments
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Initiate an HCI command.
|
||||
//
|
||||
//*****************************************************************************
|
||||
unsigned short
|
||||
hci_command_send(unsigned short usOpcode, unsigned char *pucBuff,
|
||||
unsigned char ucArgsLength)
|
||||
{
|
||||
unsigned char *stream;
|
||||
|
||||
stream = (pucBuff + SPI_HEADER_SIZE);
|
||||
|
||||
UINT8_TO_STREAM(stream, HCI_TYPE_CMND);
|
||||
stream = UINT16_TO_STREAM(stream, usOpcode);
|
||||
UINT8_TO_STREAM(stream, ucArgsLength);
|
||||
|
||||
//Update the opcode of the event we will be waiting for
|
||||
SpiWrite(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_data_send
|
||||
//!
|
||||
//! @param usOpcode command operation code
|
||||
//! @param ucArgs pointer to the command's arguments buffer
|
||||
//! @param usArgsLength length of the arguments
|
||||
//! @param ucTail pointer to the data buffer
|
||||
//! @param usTailLength buffer length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Initiate an HCI data write operation
|
||||
//
|
||||
//*****************************************************************************
|
||||
long
|
||||
hci_data_send(unsigned char ucOpcode,
|
||||
unsigned char *ucArgs,
|
||||
unsigned short usArgsLength,
|
||||
unsigned short usDataLength,
|
||||
const unsigned char *ucTail,
|
||||
unsigned short usTailLength)
|
||||
{
|
||||
unsigned char *stream;
|
||||
|
||||
stream = ((ucArgs) + SPI_HEADER_SIZE);
|
||||
|
||||
UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
|
||||
UINT8_TO_STREAM(stream, ucOpcode);
|
||||
UINT8_TO_STREAM(stream, usArgsLength);
|
||||
stream = UINT16_TO_STREAM(stream, usArgsLength + usDataLength + usTailLength);
|
||||
|
||||
// Send the packet over the SPI
|
||||
SpiWrite(ucArgs, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength + usDataLength + usTailLength);
|
||||
|
||||
return(ESUCCESS);
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_data_command_send
|
||||
//!
|
||||
//! @param usOpcode command operation code
|
||||
//! @param pucBuff pointer to the data buffer
|
||||
//! @param ucArgsLength arguments length
|
||||
//! @param ucDataLength data length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Prepeare HCI header and initiate an HCI data write operation
|
||||
//
|
||||
//*****************************************************************************
|
||||
void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff,
|
||||
unsigned char ucArgsLength,unsigned short ucDataLength)
|
||||
{
|
||||
unsigned char *stream = (pucBuff + SPI_HEADER_SIZE);
|
||||
|
||||
UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
|
||||
UINT8_TO_STREAM(stream, usOpcode);
|
||||
UINT8_TO_STREAM(stream, ucArgsLength);
|
||||
stream = UINT16_TO_STREAM(stream, ucArgsLength + ucDataLength);
|
||||
|
||||
// Send the command over SPI on data channel
|
||||
SpiWrite(pucBuff, ucArgsLength + ucDataLength + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_patch_send
|
||||
//!
|
||||
//! @param usOpcode command operation code
|
||||
//! @param pucBuff pointer to the command's arguments buffer
|
||||
//! @param patch pointer to patch content buffer
|
||||
//! @param usDataLength data length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Prepeare HCI header and initiate an HCI patch write operation
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength)
|
||||
{
|
||||
unsigned char *data_ptr = (pucBuff + SPI_HEADER_SIZE);
|
||||
unsigned short usTransLength;
|
||||
unsigned char *stream = (pucBuff + SPI_HEADER_SIZE);
|
||||
|
||||
UINT8_TO_STREAM(stream, HCI_TYPE_PATCH);
|
||||
UINT8_TO_STREAM(stream, ucOpcode);
|
||||
stream = UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
|
||||
|
||||
if (usDataLength <= SL_PATCH_PORTION_SIZE)
|
||||
{
|
||||
UINT16_TO_STREAM(stream, usDataLength);
|
||||
stream = UINT16_TO_STREAM(stream, usDataLength);
|
||||
memcpy((pucBuff + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, usDataLength);
|
||||
|
||||
// Update the opcode of the event we will be waiting for
|
||||
SpiWrite(pucBuff, usDataLength + HCI_PATCH_HEADER_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
usTransLength = (usDataLength/SL_PATCH_PORTION_SIZE);
|
||||
UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
|
||||
stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE);
|
||||
memcpy(pucBuff + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE);
|
||||
usDataLength -= SL_PATCH_PORTION_SIZE;
|
||||
patch += SL_PATCH_PORTION_SIZE;
|
||||
|
||||
// Update the opcode of the event we will be waiting for
|
||||
SpiWrite(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE);
|
||||
|
||||
while (usDataLength)
|
||||
{
|
||||
cc3k_int_poll();
|
||||
|
||||
if (usDataLength <= SL_PATCH_PORTION_SIZE)
|
||||
{
|
||||
usTransLength = usDataLength;
|
||||
usDataLength = 0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
usTransLength = SL_PATCH_PORTION_SIZE;
|
||||
usDataLength -= usTransLength;
|
||||
}
|
||||
|
||||
*(unsigned short *)data_ptr = usTransLength;
|
||||
memcpy(data_ptr + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength);
|
||||
patch += usTransLength;
|
||||
|
||||
// Update the opcode of the event we will be waiting for
|
||||
SpiWrite((unsigned char *)data_ptr, usTransLength + sizeof(usTransLength));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//
|
||||
//*****************************************************************************
|
336
stm/cc3k/hci.h
336
stm/cc3k/hci.h
@ -1,336 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* hci.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef __HCI_H__
|
||||
#define __HCI_H__
|
||||
|
||||
#include "cc3000_common.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define SPI_HEADER_SIZE (5)
|
||||
#define SIMPLE_LINK_HCI_CMND_HEADER_SIZE (4)
|
||||
#define HEADERS_SIZE_CMD (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
|
||||
#define SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE (5)
|
||||
#define SIMPLE_LINK_HCI_DATA_HEADER_SIZE (5)
|
||||
#define SIMPLE_LINK_HCI_PATCH_HEADER_SIZE (2)
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be used as HCI Commands and HCI Packet header defines
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define HCI_TYPE_CMND 0x1
|
||||
#define HCI_TYPE_DATA 0x2
|
||||
#define HCI_TYPE_PATCH 0x3
|
||||
#define HCI_TYPE_EVNT 0x4
|
||||
|
||||
|
||||
#define HCI_EVENT_PATCHES_DRV_REQ (1)
|
||||
#define HCI_EVENT_PATCHES_FW_REQ (2)
|
||||
#define HCI_EVENT_PATCHES_BOOTLOAD_REQ (3)
|
||||
|
||||
|
||||
#define HCI_CMND_WLAN_BASE (0x0000)
|
||||
#define HCI_CMND_WLAN_CONNECT 0x0001
|
||||
#define HCI_CMND_WLAN_DISCONNECT 0x0002
|
||||
#define HCI_CMND_WLAN_IOCTL_SET_SCANPARAM 0x0003
|
||||
#define HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY 0x0004
|
||||
#define HCI_CMND_WLAN_IOCTL_ADD_PROFILE 0x0005
|
||||
#define HCI_CMND_WLAN_IOCTL_DEL_PROFILE 0x0006
|
||||
#define HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS 0x0007
|
||||
#define HCI_CMND_EVENT_MASK 0x0008
|
||||
#define HCI_CMND_WLAN_IOCTL_STATUSGET 0x0009
|
||||
#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START 0x000A
|
||||
#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP 0x000B
|
||||
#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX 0x000C
|
||||
#define HCI_CMND_WLAN_CONFIGURE_PATCH 0x000D
|
||||
|
||||
|
||||
#define HCI_CMND_SOCKET_BASE 0x1000
|
||||
#define HCI_CMND_SOCKET 0x1001
|
||||
#define HCI_CMND_BIND 0x1002
|
||||
#define HCI_CMND_RECV 0x1004
|
||||
#define HCI_CMND_ACCEPT 0x1005
|
||||
#define HCI_CMND_LISTEN 0x1006
|
||||
#define HCI_CMND_CONNECT 0x1007
|
||||
#define HCI_CMND_BSD_SELECT 0x1008
|
||||
#define HCI_CMND_SETSOCKOPT 0x1009
|
||||
#define HCI_CMND_GETSOCKOPT 0x100A
|
||||
#define HCI_CMND_CLOSE_SOCKET 0x100B
|
||||
#define HCI_CMND_RECVFROM 0x100D
|
||||
#define HCI_CMND_GETHOSTNAME 0x1010
|
||||
#define HCI_CMND_MDNS_ADVERTISE 0x1011
|
||||
|
||||
|
||||
#define HCI_DATA_BASE 0x80
|
||||
|
||||
#define HCI_CMND_SEND (0x01 + HCI_DATA_BASE)
|
||||
#define HCI_CMND_SENDTO (0x03 + HCI_DATA_BASE)
|
||||
#define HCI_DATA_BSD_RECVFROM (0x04 + HCI_DATA_BASE)
|
||||
#define HCI_DATA_BSD_RECV (0x05 + HCI_DATA_BASE)
|
||||
|
||||
|
||||
#define HCI_CMND_NVMEM_CBASE (0x0200)
|
||||
|
||||
|
||||
#define HCI_CMND_NVMEM_CREATE_ENTRY (0x0203)
|
||||
#define HCI_CMND_NVMEM_SWAP_ENTRY (0x0205)
|
||||
#define HCI_CMND_NVMEM_READ (0x0201)
|
||||
#define HCI_CMND_NVMEM_WRITE (0x0090)
|
||||
#define HCI_CMND_NVMEM_WRITE_PATCH (0x0204)
|
||||
#define HCI_CMND_READ_SP_VERSION (0x0207)
|
||||
|
||||
#define HCI_CMND_READ_BUFFER_SIZE 0x400B
|
||||
#define HCI_CMND_SIMPLE_LINK_START 0x4000
|
||||
|
||||
#define HCI_CMND_NETAPP_BASE 0x2000
|
||||
|
||||
#define HCI_NETAPP_DHCP (0x0001 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_PING_SEND (0x0002 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_PING_REPORT (0x0003 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_PING_STOP (0x0004 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_IPCONFIG (0x0005 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_ARP_FLUSH (0x0006 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_SET_DEBUG_LEVEL (0x0008 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_SET_TIMERS (0x0009 + HCI_CMND_NETAPP_BASE)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be used as HCI Events defines
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define HCI_EVNT_WLAN_BASE 0x0000
|
||||
#define HCI_EVNT_WLAN_CONNECT 0x0001
|
||||
#define HCI_EVNT_WLAN_DISCONNECT \
|
||||
0x0002
|
||||
#define HCI_EVNT_WLAN_IOCTL_ADD_PROFILE \
|
||||
0x0005
|
||||
|
||||
|
||||
#define HCI_EVNT_SOCKET HCI_CMND_SOCKET
|
||||
#define HCI_EVNT_BIND HCI_CMND_BIND
|
||||
#define HCI_EVNT_RECV HCI_CMND_RECV
|
||||
#define HCI_EVNT_ACCEPT HCI_CMND_ACCEPT
|
||||
#define HCI_EVNT_LISTEN HCI_CMND_LISTEN
|
||||
#define HCI_EVNT_CONNECT HCI_CMND_CONNECT
|
||||
#define HCI_EVNT_SELECT HCI_CMND_BSD_SELECT
|
||||
#define HCI_EVNT_CLOSE_SOCKET HCI_CMND_CLOSE_SOCKET
|
||||
#define HCI_EVNT_RECVFROM HCI_CMND_RECVFROM
|
||||
#define HCI_EVNT_SETSOCKOPT HCI_CMND_SETSOCKOPT
|
||||
#define HCI_EVNT_GETSOCKOPT HCI_CMND_GETSOCKOPT
|
||||
#define HCI_EVNT_BSD_GETHOSTBYNAME HCI_CMND_GETHOSTNAME
|
||||
#define HCI_EVNT_MDNS_ADVERTISE HCI_CMND_MDNS_ADVERTISE
|
||||
|
||||
#define HCI_EVNT_SEND 0x1003
|
||||
#define HCI_EVNT_WRITE 0x100E
|
||||
#define HCI_EVNT_SENDTO 0x100F
|
||||
|
||||
#define HCI_EVNT_PATCHES_REQ 0x1000
|
||||
|
||||
#define HCI_EVNT_UNSOL_BASE 0x4000
|
||||
|
||||
#define HCI_EVNT_WLAN_UNSOL_BASE (0x8000)
|
||||
|
||||
#define HCI_EVNT_WLAN_UNSOL_CONNECT (0x0001 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_UNSOL_DISCONNECT (0x0002 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_UNSOL_INIT (0x0004 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_TX_COMPLETE (0x0008 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_UNSOL_DHCP (0x0010 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_ASYNC_PING_REPORT (0x0040 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE (0x0080 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_KEEPALIVE (0x0200 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_BSD_TCP_CLOSE_WAIT (0x0800 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
|
||||
#define HCI_EVNT_DATA_UNSOL_FREE_BUFF \
|
||||
0x4100
|
||||
|
||||
#define HCI_EVNT_NVMEM_CREATE_ENTRY \
|
||||
HCI_CMND_NVMEM_CREATE_ENTRY
|
||||
#define HCI_EVNT_NVMEM_SWAP_ENTRY HCI_CMND_NVMEM_SWAP_ENTRY
|
||||
|
||||
#define HCI_EVNT_NVMEM_READ HCI_CMND_NVMEM_READ
|
||||
#define HCI_EVNT_NVMEM_WRITE (0x0202)
|
||||
|
||||
#define HCI_EVNT_READ_SP_VERSION \
|
||||
HCI_CMND_READ_SP_VERSION
|
||||
|
||||
#define HCI_EVNT_INPROGRESS 0xFFFF
|
||||
|
||||
|
||||
#define HCI_DATA_RECVFROM 0x84
|
||||
#define HCI_DATA_RECV 0x85
|
||||
#define HCI_DATA_NVMEM 0x91
|
||||
|
||||
#define HCI_EVENT_CC3000_CAN_SHUT_DOWN 0x99
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Prototypes for the structures for APIs.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#define HCI_DATA_HEADER_SIZE (5)
|
||||
#define HCI_EVENT_HEADER_SIZE (5)
|
||||
#define HCI_DATA_CMD_HEADER_SIZE (5)
|
||||
#define HCI_PATCH_HEADER_SIZE (6)
|
||||
|
||||
#define HCI_PACKET_TYPE_OFFSET (0)
|
||||
#define HCI_PACKET_ARGSIZE_OFFSET (2)
|
||||
#define HCI_PACKET_LENGTH_OFFSET (3)
|
||||
|
||||
|
||||
#define HCI_EVENT_OPCODE_OFFSET (1)
|
||||
#define HCI_EVENT_LENGTH_OFFSET (3)
|
||||
#define HCI_EVENT_STATUS_OFFSET (4)
|
||||
#define HCI_DATA_LENGTH_OFFSET (3)
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Prototypes for the APIs.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_command_send
|
||||
//!
|
||||
//! @param usOpcode command operation code
|
||||
//! @param pucBuff pointer to the command's arguments buffer
|
||||
//! @param ucArgsLength length of the arguments
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Initiate an HCI command.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern unsigned short hci_command_send(unsigned short usOpcode,
|
||||
unsigned char *ucArgs,
|
||||
unsigned char ucArgsLength);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_data_send
|
||||
//!
|
||||
//! @param usOpcode command operation code
|
||||
//! @param ucArgs pointer to the command's arguments buffer
|
||||
//! @param usArgsLength length of the arguments
|
||||
//! @param ucTail pointer to the data buffer
|
||||
//! @param usTailLength buffer length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Initiate an HCI data write operation
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long hci_data_send(unsigned char ucOpcode,
|
||||
unsigned char *ucArgs,
|
||||
unsigned short usArgsLength,
|
||||
unsigned short usDataLength,
|
||||
const unsigned char *ucTail,
|
||||
unsigned short usTailLength);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_data_command_send
|
||||
//!
|
||||
//! @param usOpcode command operation code
|
||||
//! @param pucBuff pointer to the data buffer
|
||||
//! @param ucArgsLength arguments length
|
||||
//! @param ucDataLength data length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Prepare HCI header and initiate an HCI data write operation
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff,
|
||||
unsigned char ucArgsLength, unsigned short ucDataLength);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_patch_send
|
||||
//!
|
||||
//! @param usOpcode command operation code
|
||||
//! @param pucBuff pointer to the command's arguments buffer
|
||||
//! @param patch pointer to patch content buffer
|
||||
//! @param usDataLength data length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Prepare HCI header and initiate an HCI patch write operation
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength);
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __HCI_H__
|
@ -1,55 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* host_driver_version.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef __HOST_DRIVER_VERSION_H__
|
||||
#define __HOST_DRIVER_VERSION_H__
|
||||
|
||||
#define DRIVER_VERSION_NUMBER 13
|
||||
|
||||
|
||||
|
||||
#endif // __VERSION_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,477 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* netapp.c - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include <stdint.h>
|
||||
|
||||
#include "netapp.h"
|
||||
#include "hci.h"
|
||||
#include "socket.h"
|
||||
#include "evnt_handler.h"
|
||||
#include "nvmem.h"
|
||||
|
||||
#define MIN_TIMER_VAL_SECONDS 20
|
||||
#define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \
|
||||
{ \
|
||||
t = MIN_TIMER_VAL_SECONDS; \
|
||||
}
|
||||
|
||||
|
||||
#define NETAPP_DHCP_PARAMS_LEN (20)
|
||||
#define NETAPP_SET_TIMER_PARAMS_LEN (20)
|
||||
#define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN (4)
|
||||
#define NETAPP_PING_SEND_PARAMS_LEN (16)
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_config_mac_adrress
|
||||
//!
|
||||
//! @param mac device mac address, 6 bytes. Saved: yes
|
||||
//!
|
||||
//! @return return on success 0, otherwise error.
|
||||
//!
|
||||
//! @brief Configure device MAC address and store it in NVMEM.
|
||||
//! The value of the MAC address configured through the API will
|
||||
//! be stored in CC3000 non volatile memory, thus preserved
|
||||
//! over resets.
|
||||
//
|
||||
//*****************************************************************************
|
||||
long netapp_config_mac_adrress(unsigned char * mac)
|
||||
{
|
||||
return nvmem_set_mac_address(mac);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_dhcp
|
||||
//!
|
||||
//! @param aucIP device mac address, 6 bytes. Saved: yes
|
||||
//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes
|
||||
//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes
|
||||
//! @param aucDNSServer device mac address, 6 bytes. Saved: yes
|
||||
//!
|
||||
//! @return return on success 0, otherwise error.
|
||||
//!
|
||||
//! @brief netapp_dhcp is used to configure the network interface,
|
||||
//! static or dynamic (DHCP).\n In order to activate DHCP mode,
|
||||
//! aucIP, aucSubnetMask, aucDefaultGateway must be 0.
|
||||
//! The default mode of CC3000 is DHCP mode.
|
||||
//! Note that the configuration is saved in non volatile memory
|
||||
//! and thus preserved over resets.
|
||||
//!
|
||||
//! @note If the mode is altered a reset of CC3000 device is required
|
||||
//! in order to apply changes.\nAlso note that asynchronous event
|
||||
//! of DHCP_EVENT, which is generated when an IP address is
|
||||
//! allocated either by the DHCP server or due to static
|
||||
//! allocation is generated only upon a connection to the
|
||||
//! AP was established.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer)
|
||||
{
|
||||
signed char scRet;
|
||||
unsigned char *ptr;
|
||||
unsigned char *args;
|
||||
|
||||
scRet = EFAIL;
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
args = (ptr + HEADERS_SIZE_CMD);
|
||||
|
||||
// Fill in temporary command buffer
|
||||
ARRAY_TO_STREAM(args,aucIP,4);
|
||||
ARRAY_TO_STREAM(args,aucSubnetMask,4);
|
||||
ARRAY_TO_STREAM(args,aucDefaultGateway,4);
|
||||
args = UINT32_TO_STREAM(args, 0);
|
||||
ARRAY_TO_STREAM(args,aucDNSServer,4);
|
||||
|
||||
// Initiate a HCI command
|
||||
hci_command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN);
|
||||
|
||||
// Wait for command complete event
|
||||
SimpleLinkWaitEvent(HCI_NETAPP_DHCP, &scRet);
|
||||
|
||||
return(scRet);
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_timeout_values
|
||||
//!
|
||||
//! @param aucDHCP DHCP lease time request, also impact
|
||||
//! the DHCP renew timeout. Range: [0-0xffffffff] seconds,
|
||||
//! 0 or 0xffffffff == infinity lease timeout.
|
||||
//! Resolution:10 seconds. Influence: only after
|
||||
//! reconnecting to the AP.
|
||||
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds.
|
||||
//! The parameter is saved into the CC3000 NVMEM.
|
||||
//! The default value on CC3000 is 14400 seconds.
|
||||
//!
|
||||
//! @param aucARP ARP refresh timeout, if ARP entry is not updated by
|
||||
//! incoming packet, the ARP entry will be deleted by
|
||||
//! the end of the timeout.
|
||||
//! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout
|
||||
//! Resolution: 10 seconds. Influence: on runtime.
|
||||
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds
|
||||
//! The parameter is saved into the CC3000 NVMEM.
|
||||
//! The default value on CC3000 is 3600 seconds.
|
||||
//!
|
||||
//! @param aucKeepalive Keepalive event sent by the end of keepalive timeout
|
||||
//! Range: [0-0xffffffff] seconds, 0 == infinity timeout
|
||||
//! Resolution: 10 seconds.
|
||||
//! Influence: on runtime.
|
||||
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
|
||||
//! The parameter is saved into the CC3000 NVMEM.
|
||||
//! The default value on CC3000 is 10 seconds.
|
||||
//!
|
||||
//! @param aucInactivity Socket inactivity timeout, socket timeout is
|
||||
//! refreshed by incoming or outgoing packet, by the
|
||||
//! end of the socket timeout the socket will be closed
|
||||
//! Range: [0-0xffffffff] sec, 0 == infinity timeout.
|
||||
//! Resolution: 10 seconds. Influence: on runtime.
|
||||
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
|
||||
//! The parameter is saved into the CC3000 NVMEM.
|
||||
//! The default value on CC3000 is 60 seconds.
|
||||
//!
|
||||
//! @return return on success 0, otherwise error.
|
||||
//!
|
||||
//! @brief Set new timeout values. Function set new timeout values for:
|
||||
//! DHCP lease timeout, ARP refresh timeout, keepalive event
|
||||
//! timeout and socket inactivity timeout
|
||||
//!
|
||||
//! @note If a parameter set to non zero value which is less than 20s,
|
||||
//! it will be set automatically to 20s.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
long
|
||||
netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive, unsigned long *aucInactivity)
|
||||
{
|
||||
signed char scRet;
|
||||
unsigned char *ptr;
|
||||
unsigned char *args;
|
||||
|
||||
scRet = EFAIL;
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
args = (ptr + HEADERS_SIZE_CMD);
|
||||
|
||||
// Set minimal values of timers
|
||||
MIN_TIMER_SET(*aucDHCP)
|
||||
MIN_TIMER_SET(*aucARP)
|
||||
MIN_TIMER_SET(*aucKeepalive)
|
||||
MIN_TIMER_SET(*aucInactivity)
|
||||
|
||||
// Fill in temporary command buffer
|
||||
args = UINT32_TO_STREAM(args, *aucDHCP);
|
||||
args = UINT32_TO_STREAM(args, *aucARP);
|
||||
args = UINT32_TO_STREAM(args, *aucKeepalive);
|
||||
args = UINT32_TO_STREAM(args, *aucInactivity);
|
||||
|
||||
// Initiate a HCI command
|
||||
hci_command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN);
|
||||
|
||||
// Wait for command complete event
|
||||
SimpleLinkWaitEvent(HCI_NETAPP_SET_TIMERS, &scRet);
|
||||
|
||||
return(scRet);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_ping_send
|
||||
//!
|
||||
//! @param ip destination IP address
|
||||
//! @param pingAttempts number of echo requests to send
|
||||
//! @param pingSize send buffer size which may be up to 1400 bytes
|
||||
//! @param pingTimeout Time to wait for a response,in milliseconds.
|
||||
//!
|
||||
//! @return return on success 0, otherwise error.
|
||||
//!
|
||||
//! @brief send ICMP ECHO_REQUEST to network hosts
|
||||
//!
|
||||
//! @note If an operation finished successfully asynchronous ping report
|
||||
//! event will be generated. The report structure is as defined
|
||||
//! by structure netapp_pingreport_args_t.
|
||||
//!
|
||||
//! @warning Calling this function while a previous Ping Requests are in
|
||||
//! progress will stop the previous ping request.
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
long
|
||||
netapp_ping_send(uint32_t *ip, uint32_t ulPingAttempts, uint32_t ulPingSize, uint32_t ulPingTimeout)
|
||||
{
|
||||
signed char scRet;
|
||||
unsigned char *ptr, *args;
|
||||
|
||||
scRet = EFAIL;
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
args = (ptr + HEADERS_SIZE_CMD);
|
||||
|
||||
// Fill in temporary command buffer
|
||||
args = UINT32_TO_STREAM(args, *ip);
|
||||
args = UINT32_TO_STREAM(args, ulPingAttempts);
|
||||
args = UINT32_TO_STREAM(args, ulPingSize);
|
||||
args = UINT32_TO_STREAM(args, ulPingTimeout);
|
||||
|
||||
/*
|
||||
if (CC3KPrinter != 0)
|
||||
{
|
||||
for(uint8_t i=0; i<4+4+4+4; i++) {
|
||||
CC3KPrinter->print(" 0x"); CC3KPrinter->( (ptr + HEADERS_SIZE_CMD)[i], HEX);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Initiate a HCI command
|
||||
hci_command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN);
|
||||
|
||||
// Wait for command complete event
|
||||
SimpleLinkWaitEvent(HCI_NETAPP_PING_SEND, &scRet);
|
||||
|
||||
return(scRet);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_ping_report
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Request for ping status. This API triggers the CC3000 to send
|
||||
//! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT.
|
||||
//! This event will carry the report structure:
|
||||
//! netapp_pingreport_args_t. This structure is filled in with ping
|
||||
//! results up till point of triggering API.
|
||||
//! netapp_pingreport_args_t:\n packets_sent - echo sent,
|
||||
//! packets_received - echo reply, min_round_time - minimum
|
||||
//! round time, max_round_time - max round time,
|
||||
//! avg_round_time - average round time
|
||||
//!
|
||||
//! @note When a ping operation is not active, the returned structure
|
||||
//! fields are 0.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
void netapp_ping_report()
|
||||
{
|
||||
unsigned char *ptr;
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
signed char scRet;
|
||||
|
||||
scRet = EFAIL;
|
||||
|
||||
// Initiate a HCI command
|
||||
hci_command_send(HCI_NETAPP_PING_REPORT, ptr, 0);
|
||||
|
||||
// Wait for command complete event
|
||||
SimpleLinkWaitEvent(HCI_NETAPP_PING_REPORT, &scRet);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_ping_stop
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned.
|
||||
//!
|
||||
//! @brief Stop any ping request.
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
long netapp_ping_stop()
|
||||
{
|
||||
signed char scRet;
|
||||
unsigned char *ptr;
|
||||
|
||||
scRet = EFAIL;
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
|
||||
// Initiate a HCI command
|
||||
hci_command_send(HCI_NETAPP_PING_STOP, ptr, 0);
|
||||
|
||||
// Wait for command complete event
|
||||
SimpleLinkWaitEvent(HCI_NETAPP_PING_STOP, &scRet);
|
||||
|
||||
return(scRet);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_ipconfig
|
||||
//!
|
||||
//! @param[out] ipconfig This argument is a pointer to a
|
||||
//! tNetappIpconfigRetArgs structure. This structure is
|
||||
//! filled in with the network interface configuration.
|
||||
//! tNetappIpconfigRetArgs:\n aucIP - ip address,
|
||||
//! aucSubnetMask - mask, aucDefaultGateway - default
|
||||
//! gateway address, aucDHCPServer - dhcp server address
|
||||
//! aucDNSServer - dns server address, uaMacAddr - mac
|
||||
//! address, uaSSID - connected AP ssid
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Obtain the CC3000 Network interface information.
|
||||
//! Note that the information is available only after the WLAN
|
||||
//! connection was established. Calling this function before
|
||||
//! associated, will cause non-defined values to be returned.
|
||||
//!
|
||||
//! @note The function is useful for figuring out the IP Configuration of
|
||||
//! the device when DHCP is used and for figuring out the SSID of
|
||||
//! the Wireless network the device is associated with.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig )
|
||||
{
|
||||
unsigned char *ptr;
|
||||
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
|
||||
// Initiate a HCI command
|
||||
hci_command_send(HCI_NETAPP_IPCONFIG, ptr, 0);
|
||||
|
||||
// Wait for command complete event
|
||||
SimpleLinkWaitEvent(HCI_NETAPP_IPCONFIG, ipconfig );
|
||||
|
||||
}
|
||||
#else
|
||||
void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig )
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_arp_flush
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Flushes ARP table
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
long netapp_arp_flush(void)
|
||||
{
|
||||
signed char scRet;
|
||||
unsigned char *ptr;
|
||||
|
||||
scRet = EFAIL;
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
|
||||
// Initiate a HCI command
|
||||
hci_command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0);
|
||||
|
||||
// Wait for command complete event
|
||||
SimpleLinkWaitEvent(HCI_NETAPP_ARP_FLUSH, &scRet);
|
||||
|
||||
return(scRet);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_set_debug_level
|
||||
//!
|
||||
//! @param[in] level debug level. Bitwise [0-8],
|
||||
//! 0(disable)or 1(enable).\n Bitwise map: 0 - Critical
|
||||
//! message, 1 information message, 2 - core messages, 3 -
|
||||
//! HCI messages, 4 - Network stack messages, 5 - wlan
|
||||
//! messages, 6 - wlan driver messages, 7 - epprom messages,
|
||||
//! 8 - general messages. Default: 0x13f. Saved: no
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Debug messages sent via the UART debug channel, this function
|
||||
//! enable/disable the debug level
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
long netapp_set_debug_level(unsigned long ulLevel)
|
||||
{
|
||||
signed char scRet;
|
||||
unsigned char *ptr, *args;
|
||||
|
||||
scRet = EFAIL;
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
args = (ptr + HEADERS_SIZE_CMD);
|
||||
|
||||
//
|
||||
// Fill in temporary command buffer
|
||||
//
|
||||
args = UINT32_TO_STREAM(args, ulLevel);
|
||||
|
||||
|
||||
//
|
||||
// Initiate a HCI command
|
||||
//
|
||||
hci_command_send(HCI_NETAPP_SET_DEBUG_LEVEL, ptr, NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN);
|
||||
|
||||
//
|
||||
// Wait for command complete event
|
||||
//
|
||||
SimpleLinkWaitEvent(HCI_NETAPP_SET_DEBUG_LEVEL, &scRet);
|
||||
|
||||
return(scRet);
|
||||
|
||||
}
|
||||
#endif
|
@ -1,349 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* netapp.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef __NETAPP_H__
|
||||
#define __NETAPP_H__
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup netapp_api
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
typedef struct _netapp_dhcp_ret_args_t
|
||||
{
|
||||
unsigned char aucIP[4];
|
||||
unsigned char aucSubnetMask[4];
|
||||
unsigned char aucDefaultGateway[4];
|
||||
unsigned char aucDHCPServer[4];
|
||||
unsigned char aucDNSServer[4];
|
||||
}tNetappDhcpParams;
|
||||
|
||||
typedef struct _netapp_ipconfig_ret_args_t
|
||||
{
|
||||
unsigned char aucIP[4];
|
||||
unsigned char aucSubnetMask[4];
|
||||
unsigned char aucDefaultGateway[4];
|
||||
unsigned char aucDHCPServer[4];
|
||||
unsigned char aucDNSServer[4];
|
||||
unsigned char uaMacAddr[6];
|
||||
unsigned char uaSSID[32];
|
||||
}tNetappIpconfigRetArgs;
|
||||
|
||||
|
||||
/*Ping send report parameters*/
|
||||
typedef struct _netapp_pingreport_args
|
||||
{
|
||||
unsigned long packets_sent;
|
||||
unsigned long packets_received;
|
||||
unsigned long min_round_time;
|
||||
unsigned long max_round_time;
|
||||
unsigned long avg_round_time;
|
||||
} netapp_pingreport_args_t;
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_config_mac_adrress
|
||||
//!
|
||||
//! @param mac device mac address, 6 bytes. Saved: yes
|
||||
//!
|
||||
//! @return return on success 0, otherwise error.
|
||||
//!
|
||||
//! @brief Configure device MAC address and store it in NVMEM.
|
||||
//! The value of the MAC address configured through the API will
|
||||
//! be stored in CC3000 non volatile memory, thus preserved
|
||||
//! over resets.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long netapp_config_mac_adrress( unsigned char *mac );
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_dhcp
|
||||
//!
|
||||
//! @param aucIP device mac address, 6 bytes. Saved: yes
|
||||
//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes
|
||||
//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes
|
||||
//! @param aucDNSServer device mac address, 6 bytes. Saved: yes
|
||||
//!
|
||||
//! @return return on success 0, otherwise error.
|
||||
//!
|
||||
//! @brief netapp_dhcp is used to configure the network interface,
|
||||
//! static or dynamic (DHCP).\n In order to activate DHCP mode,
|
||||
//! aucIP, aucSubnetMask, aucDefaultGateway must be 0.
|
||||
//! The default mode of CC3000 is DHCP mode.
|
||||
//! Note that the configuration is saved in non volatile memory
|
||||
//! and thus preserved over resets.
|
||||
//!
|
||||
//! @note If the mode is altered a reset of CC3000 device is required
|
||||
//! in order to apply changes.\nAlso note that asynchronous event
|
||||
//! of DHCP_EVENT, which is generated when an IP address is
|
||||
//! allocated either by the DHCP server or due to static
|
||||
//! allocation is generated only upon a connection to the
|
||||
//! AP was established.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer);
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_timeout_values
|
||||
//!
|
||||
//! @param aucDHCP DHCP lease time request, also impact
|
||||
//! the DHCP renew timeout. Range: [0-0xffffffff] seconds,
|
||||
//! 0 or 0xffffffff == infinity lease timeout.
|
||||
//! Resolution:10 seconds. Influence: only after
|
||||
//! reconnecting to the AP.
|
||||
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds.
|
||||
//! The parameter is saved into the CC3000 NVMEM.
|
||||
//! The default value on CC3000 is 14400 seconds.
|
||||
//!
|
||||
//! @param aucARP ARP refresh timeout, if ARP entry is not updated by
|
||||
//! incoming packet, the ARP entry will be deleted by
|
||||
//! the end of the timeout.
|
||||
//! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout
|
||||
//! Resolution: 10 seconds. Influence: on runtime.
|
||||
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds
|
||||
//! The parameter is saved into the CC3000 NVMEM.
|
||||
//! The default value on CC3000 is 3600 seconds.
|
||||
//!
|
||||
//! @param aucKeepalive Keepalive event sent by the end of keepalive timeout
|
||||
//! Range: [0-0xffffffff] seconds, 0 == infinity timeout
|
||||
//! Resolution: 10 seconds.
|
||||
//! Influence: on runtime.
|
||||
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
|
||||
//! The parameter is saved into the CC3000 NVMEM.
|
||||
//! The default value on CC3000 is 10 seconds.
|
||||
//!
|
||||
//! @param aucInactivity Socket inactivity timeout, socket timeout is
|
||||
//! refreshed by incoming or outgoing packet, by the
|
||||
//! end of the socket timeout the socket will be closed
|
||||
//! Range: [0-0xffffffff] sec, 0 == infinity timeout.
|
||||
//! Resolution: 10 seconds. Influence: on runtime.
|
||||
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
|
||||
//! The parameter is saved into the CC3000 NVMEM.
|
||||
//! The default value on CC3000 is 60 seconds.
|
||||
//!
|
||||
//! @return return on success 0, otherwise error.
|
||||
//!
|
||||
//! @brief Set new timeout values. Function set new timeout values for:
|
||||
//! DHCP lease timeout, ARP refresh timeout, keepalive event
|
||||
//! timeout and socket inactivity timeout
|
||||
//!
|
||||
//! @note If a parameter set to non zero value which is less than 20s,
|
||||
//! it will be set automatically to 20s.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive, unsigned long *aucInactivity);
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_ping_send
|
||||
//!
|
||||
//! @param ip destination IP address
|
||||
//! @param pingAttempts number of echo requests to send
|
||||
//! @param pingSize send buffer size which may be up to 1400 bytes
|
||||
//! @param pingTimeout Time to wait for a response,in milliseconds.
|
||||
//!
|
||||
//! @return return on success 0, otherwise error.
|
||||
//!
|
||||
//! @brief send ICMP ECHO_REQUEST to network hosts
|
||||
//!
|
||||
//! @note If an operation finished successfully asynchronous ping report
|
||||
//! event will be generated. The report structure is as defined
|
||||
//! by structure netapp_pingreport_args_t.
|
||||
//!
|
||||
//! @warning Calling this function while a previous Ping Requests are in
|
||||
//! progress will stop the previous ping request.
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern long netapp_ping_send(uint32_t *ip, uint32_t ulPingAttempts, uint32_t ulPingSize, uint32_t ulPingTimeout);
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_ping_stop
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned.
|
||||
//!
|
||||
//! @brief Stop any ping request.
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern long netapp_ping_stop();
|
||||
#endif
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_ping_report
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Request for ping status. This API triggers the CC3000 to send
|
||||
//! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT.
|
||||
//! This event will carry the report structure:
|
||||
//! netapp_pingreport_args_t. This structure is filled in with ping
|
||||
//! results up till point of triggering API.
|
||||
//! netapp_pingreport_args_t:\n packets_sent - echo sent,
|
||||
//! packets_received - echo reply, min_round_time - minimum
|
||||
//! round time, max_round_time - max round time,
|
||||
//! avg_round_time - average round time
|
||||
//!
|
||||
//! @note When a ping operation is not active, the returned structure
|
||||
//! fields are 0.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern void netapp_ping_report();
|
||||
#endif
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_ipconfig
|
||||
//!
|
||||
//! @param[out] ipconfig This argument is a pointer to a
|
||||
//! tNetappIpconfigRetArgs structure. This structure is
|
||||
//! filled in with the network interface configuration.
|
||||
//! tNetappIpconfigRetArgs:\n aucIP - ip address,
|
||||
//! aucSubnetMask - mask, aucDefaultGateway - default
|
||||
//! gateway address, aucDHCPServer - dhcp server address
|
||||
//! aucDNSServer - dns server address, uaMacAddr - mac
|
||||
//! address, uaSSID - connected AP ssid
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Obtain the CC3000 Network interface information.
|
||||
//! Note that the information is available only after the WLAN
|
||||
//! connection was established. Calling this function before
|
||||
//! associated, will cause non-defined values to be returned.
|
||||
//!
|
||||
//! @note The function is useful for figuring out the IP Configuration of
|
||||
//! the device when DHCP is used and for figuring out the SSID of
|
||||
//! the Wireless network the device is associated with.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
extern void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig );
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_arp_flush
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Flushes ARP table
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern long netapp_arp_flush();
|
||||
#endif
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_set_debug_level
|
||||
//!
|
||||
//! @param[in] level debug level. Bitwise [0-8],
|
||||
//! 0(disable)or 1(enable).\n Bitwise map: 0 - Critical
|
||||
//! message, 1 information message, 2 - core messages, 3 -
|
||||
//! HCI messages, 4 - Network stack messages, 5 - wlan
|
||||
//! messages, 6 - wlan driver messages, 7 - epprom messages,
|
||||
//! 8 - general messages. Default: 0x13f. Saved: no
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Debug messages sent via the UART debug channel, this function
|
||||
//! enable/disable the debug level
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
long netapp_set_debug_level(unsigned long ulLevel);
|
||||
#endif
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __NETAPP_H__
|
||||
|
366
stm/cc3k/nvmem.c
366
stm/cc3k/nvmem.c
@ -1,366 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* nvmem.c - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup nvmem_api
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nvmem.h"
|
||||
#include "hci.h"
|
||||
#include "socket.h"
|
||||
#include "evnt_handler.h"
|
||||
#include "ccdebug.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Prototypes for the structures for APIs.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#define NVMEM_READ_PARAMS_LEN (12)
|
||||
#define NVMEM_CREATE_PARAMS_LEN (8)
|
||||
#define NVMEM_WRITE_PARAMS_LEN (16)
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_read
|
||||
//!
|
||||
//! @param ulFileId nvmem file id:\n
|
||||
//! NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID,
|
||||
//! NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID,
|
||||
//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
|
||||
//! NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID,
|
||||
//! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID,
|
||||
//! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID,
|
||||
//! and user files 12-15.
|
||||
//! @param ulLength number of bytes to read
|
||||
//! @param ulOffset ulOffset in file from where to read
|
||||
//! @param buff output buffer pointer
|
||||
//!
|
||||
//! @return number of bytes read, otherwise error.
|
||||
//!
|
||||
//! @brief Reads data from the file referred by the ulFileId parameter.
|
||||
//! Reads data from file ulOffset till length. Err if the file can't
|
||||
//! be used, is invalid, or if the read is out of bounds.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
signed long
|
||||
nvmem_read(unsigned long ulFileId, unsigned long ulLength, unsigned long ulOffset, unsigned char *buff)
|
||||
{
|
||||
unsigned char ucStatus = 0xFF;
|
||||
unsigned char *ptr;
|
||||
unsigned char *args;
|
||||
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
args = (ptr + HEADERS_SIZE_CMD);
|
||||
|
||||
// Fill in HCI packet structure
|
||||
args = UINT32_TO_STREAM(args, ulFileId);
|
||||
args = UINT32_TO_STREAM(args, ulLength);
|
||||
args = UINT32_TO_STREAM(args, ulOffset);
|
||||
|
||||
// Initiate a HCI command
|
||||
hci_command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN);
|
||||
SimpleLinkWaitEvent(HCI_CMND_NVMEM_READ, &ucStatus);
|
||||
|
||||
// In case there is data - read it - even if an error code is returned
|
||||
// Note: It is the user responsibility to ignore the data in case of an error code
|
||||
|
||||
// Wait for the data in a synchronous way. Here we assume that the buffer is
|
||||
// big enough to store also parameters of nvmem
|
||||
|
||||
SimpleLinkWaitData(buff, 0, 0);
|
||||
|
||||
return(ucStatus);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_write
|
||||
//!
|
||||
//! @param ulFileId nvmem file id:\n
|
||||
//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
|
||||
//! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID,
|
||||
//! and user files 12-15.
|
||||
//! @param ulLength number of bytes to write
|
||||
//! @param ulEntryOffset offset in file to start write operation from
|
||||
//! @param buff data to write
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Write data to nvmem.
|
||||
//! writes data to file referred by the ulFileId parameter.
|
||||
//! Writes data to file ulOffset till ulLength.The file id will be
|
||||
//! marked invalid till the write is done. The file entry doesn't
|
||||
//! need to be valid - only allocated.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
signed long
|
||||
nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long
|
||||
ulEntryOffset, unsigned char *buff)
|
||||
{
|
||||
long iRes;
|
||||
unsigned char *ptr;
|
||||
unsigned char *args;
|
||||
|
||||
iRes = EFAIL;
|
||||
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE);
|
||||
|
||||
// Fill in HCI packet structure
|
||||
args = UINT32_TO_STREAM(args, ulFileId);
|
||||
args = UINT32_TO_STREAM(args, 12);
|
||||
args = UINT32_TO_STREAM(args, ulLength);
|
||||
args = UINT32_TO_STREAM(args, ulEntryOffset);
|
||||
|
||||
memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE +
|
||||
NVMEM_WRITE_PARAMS_LEN),buff,ulLength);
|
||||
#if (DEBUG_MODE == 1)
|
||||
PRINT_F("Writing:\t");
|
||||
for (uint8_t i=0; i<ulLength; i++) {
|
||||
PRINT_F("0x");
|
||||
printHex(buff[i]);
|
||||
PRINT_F(", ");
|
||||
}
|
||||
PRINT_F("\n\r");
|
||||
#endif
|
||||
// Initiate a HCI command but it will come on data channel
|
||||
hci_data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN,
|
||||
ulLength);
|
||||
|
||||
SimpleLinkWaitEvent(HCI_EVNT_NVMEM_WRITE, &iRes);
|
||||
|
||||
return(iRes);
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_set_mac_address
|
||||
//!
|
||||
//! @param mac mac address to be set
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Write MAC address to EEPROM.
|
||||
//! mac address as appears over the air (OUI first)
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
unsigned char nvmem_set_mac_address(unsigned char *mac)
|
||||
{
|
||||
return nvmem_write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_get_mac_address
|
||||
//!
|
||||
//! @param[out] mac mac address
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Read MAC address from EEPROM.
|
||||
//! mac address as appears over the air (OUI first)
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
unsigned char nvmem_get_mac_address(unsigned char *mac)
|
||||
{
|
||||
return nvmem_read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_write_patch
|
||||
//!
|
||||
//! @param ulFileId nvmem file id:\n
|
||||
//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
|
||||
//! @param spLength number of bytes to write
|
||||
//! @param spData SP data to write
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief program a patch to a specific file ID.
|
||||
//! The SP data is assumed to be organized in 2-dimensional.
|
||||
//! Each line is SP_PORTION_SIZE bytes long. Actual programming is
|
||||
//! applied in SP_PORTION_SIZE bytes portions.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const uint8_t *spData)
|
||||
{
|
||||
unsigned char status = 0;
|
||||
unsigned short offset = 0;
|
||||
unsigned char* spDataPtr = (unsigned char*)spData;
|
||||
|
||||
while ((status == 0) && (spLength >= SP_PORTION_SIZE))
|
||||
{
|
||||
#if (DEBUG_MODE == 1)
|
||||
PRINT_F("Writing: "); printDec16(offset); PRINT_F("\t");
|
||||
for (uint8_t i=0; i<SP_PORTION_SIZE; i++) {
|
||||
PRINT_F("0x");
|
||||
printHex(spDataPtr[i]);
|
||||
PRINT_F(", ");
|
||||
}
|
||||
PRINT_F("\n\r");
|
||||
#endif
|
||||
status = nvmem_write(ulFileId, SP_PORTION_SIZE, offset, spDataPtr);
|
||||
offset += SP_PORTION_SIZE;
|
||||
spLength -= SP_PORTION_SIZE;
|
||||
spDataPtr += SP_PORTION_SIZE;
|
||||
}
|
||||
|
||||
if (status !=0)
|
||||
{
|
||||
// NVMEM error occurred
|
||||
return status;
|
||||
}
|
||||
|
||||
if (spLength != 0)
|
||||
{
|
||||
// if reached here, a reminder is left
|
||||
status = nvmem_write(ulFileId, spLength, offset, spDataPtr);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_read_sp_version
|
||||
//!
|
||||
//! @param[out] patchVer first number indicates package ID and the second
|
||||
//! number indicates package build number
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Read patch version. read package version (WiFi FW patch,
|
||||
//! driver-supplicant-NS patch, bootloader patch)
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
uint8_t nvmem_read_sp_version(uint8_t* patchVer)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
// 1st byte is the status and the rest is the SP version
|
||||
uint8_t retBuf[5];
|
||||
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
|
||||
// Initiate a HCI command, no args are required
|
||||
hci_command_send(HCI_CMND_READ_SP_VERSION, ptr, 0);
|
||||
SimpleLinkWaitEvent(HCI_CMND_READ_SP_VERSION, retBuf);
|
||||
|
||||
// package ID
|
||||
*patchVer = retBuf[3];
|
||||
// package build number
|
||||
*(patchVer+1) = retBuf[4];
|
||||
|
||||
return(retBuf[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_create_entry
|
||||
//!
|
||||
//! @param ulFileId nvmem file Id:\n
|
||||
//! * NVMEM_AES128_KEY_FILEID: 12
|
||||
//! * NVMEM_SHARED_MEM_FILEID: 13
|
||||
//! * and fileIDs 14 and 15
|
||||
//! @param ulNewLen entry ulLength
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Create new file entry and allocate space on the NVMEM.
|
||||
//! Applies only to user files.
|
||||
//! Modify the size of file.
|
||||
//! If the entry is unallocated - allocate it to size
|
||||
//! ulNewLen (marked invalid).
|
||||
//! If it is allocated then deallocate it first.
|
||||
//! To just mark the file as invalid without resizing -
|
||||
//! set ulNewLen=0.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
int8_t
|
||||
nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen)
|
||||
{
|
||||
unsigned char *ptr;
|
||||
unsigned char *args;
|
||||
int8_t retval;
|
||||
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
args = (ptr + HEADERS_SIZE_CMD);
|
||||
|
||||
// Fill in HCI packet structure
|
||||
args = UINT32_TO_STREAM(args, ulFileId);
|
||||
args = UINT32_TO_STREAM(args, ulNewLen);
|
||||
|
||||
// Initiate a HCI command
|
||||
hci_command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN);
|
||||
|
||||
SimpleLinkWaitEvent(HCI_CMND_NVMEM_CREATE_ENTRY, &retval);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
256
stm/cc3k/nvmem.h
256
stm/cc3k/nvmem.h
@ -1,256 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* nvmem.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef __NVRAM_H__
|
||||
#define __NVRAM_H__
|
||||
|
||||
#include "cc3000_common.h"
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup nvmem_api
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Definitions for File IDs
|
||||
**
|
||||
****************************************************************************/
|
||||
/* NVMEM file ID - system files*/
|
||||
#define NVMEM_NVS_FILEID (0)
|
||||
#define NVMEM_NVS_SHADOW_FILEID (1)
|
||||
#define NVMEM_WLAN_CONFIG_FILEID (2)
|
||||
#define NVMEM_WLAN_CONFIG_SHADOW_FILEID (3)
|
||||
#define NVMEM_WLAN_DRIVER_SP_FILEID (4)
|
||||
#define NVMEM_WLAN_FW_SP_FILEID (5)
|
||||
#define NVMEM_MAC_FILEID (6)
|
||||
#define NVMEM_FRONTEND_VARS_FILEID (7)
|
||||
#define NVMEM_IP_CONFIG_FILEID (8)
|
||||
#define NVMEM_IP_CONFIG_SHADOW_FILEID (9)
|
||||
#define NVMEM_BOOTLOADER_SP_FILEID (10)
|
||||
#define NVMEM_RM_FILEID (11)
|
||||
|
||||
/* NVMEM file ID - user files*/
|
||||
#define NVMEM_AES128_KEY_FILEID (12)
|
||||
#define NVMEM_SHARED_MEM_FILEID (13)
|
||||
|
||||
/* max entry in order to invalid nvmem */
|
||||
#define NVMEM_MAX_ENTRY (16)
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_read
|
||||
//!
|
||||
//! @param ulFileId nvmem file id:\n
|
||||
//! NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID,
|
||||
//! NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID,
|
||||
//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
|
||||
//! NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID,
|
||||
//! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID,
|
||||
//! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID,
|
||||
//! and user files 12-15.
|
||||
//! @param ulLength number of bytes to read
|
||||
//! @param ulOffset ulOffset in file from where to read
|
||||
//! @param buff output buffer pointer
|
||||
//!
|
||||
//! @return number of bytes read, otherwise error.
|
||||
//!
|
||||
//! @brief Reads data from the file referred by the ulFileId parameter.
|
||||
//! Reads data from file ulOffset till length. Err if the file can't
|
||||
//! be used, is invalid, or if the read is out of bounds.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
extern signed long nvmem_read(unsigned long file_id, unsigned long length, unsigned long offset, unsigned char *buff);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_write
|
||||
//!
|
||||
//! @param ulFileId nvmem file id:\n
|
||||
//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
|
||||
//! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID,
|
||||
//! and user files 12-15.
|
||||
//! @param ulLength number of bytes to write
|
||||
//! @param ulEntryOffset offset in file to start write operation from
|
||||
//! @param buff data to write
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Write data to nvmem.
|
||||
//! writes data to file referred by the ulFileId parameter.
|
||||
//! Writes data to file ulOffset till ulLength.The file id will be
|
||||
//! marked invalid till the write is done. The file entry doesn't
|
||||
//! need to be valid - only allocated.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
extern signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long ulEntryOffset, unsigned char *buff);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_set_mac_address
|
||||
//!
|
||||
//! @param mac mac address to be set
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Write MAC address to EEPROM.
|
||||
//! mac address as appears over the air (OUI first)
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern unsigned char nvmem_set_mac_address(unsigned char *mac);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_get_mac_address
|
||||
//!
|
||||
//! @param[out] mac mac address
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Read MAC address from EEPROM.
|
||||
//! mac address as appears over the air (OUI first)
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern unsigned char nvmem_get_mac_address(unsigned char *mac);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_write_patch
|
||||
//!
|
||||
//! @param ulFileId nvmem file id:\n
|
||||
//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
|
||||
//! @param spLength number of bytes to write
|
||||
//! @param spData SP data to write
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief program a patch to a specific file ID.
|
||||
//! The SP data is assumed to be organized in 2-dimensional.
|
||||
//! Each line is SP_PORTION_SIZE bytes long. Actual programming is
|
||||
//! applied in SP_PORTION_SIZE bytes portions.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const unsigned char *spData);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_read_sp_version
|
||||
//!
|
||||
//! @param[out] patchVer first number indicates package ID and the second
|
||||
//! number indicates package build number
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Read patch version. read package version (WiFi FW patch,
|
||||
//! driver-supplicant-NS patch, bootloader patch)
|
||||
//!
|
||||
//*****************************************************************************
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern unsigned char nvmem_read_sp_version(unsigned char* patchVer);
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! nvmem_create_entry
|
||||
//!
|
||||
//! @param ulFileId nvmem file Id:\n
|
||||
//! * NVMEM_AES128_KEY_FILEID: 12
|
||||
//! * NVMEM_SHARED_MEM_FILEID: 13
|
||||
//! * and fileIDs 14 and 15
|
||||
//! @param ulNewLen entry ulLength
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Create new file entry and allocate space on the NVMEM.
|
||||
//! Applies only to user files.
|
||||
//! Modify the size of file.
|
||||
//! If the entry is unallocated - allocate it to size
|
||||
//! ulNewLen (marked invalid).
|
||||
//! If it is allocated then deallocate it first.
|
||||
//! To just mark the file as invalid without resizing -
|
||||
//! set ulNewLen=0.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern int8_t nvmem_create_entry(unsigned long file_id, unsigned long newlen);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __NVRAM_H__
|
@ -1,204 +0,0 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "stm32f4xx_rcc.h"
|
||||
#include <stm32f4xx_syscfg.h>
|
||||
#include "stm32f4xx_gpio.h"
|
||||
#include <stm32f4xx_exti.h>
|
||||
#include <stm_misc.h>
|
||||
#include "stm32f4xx_spi.h"
|
||||
|
||||
#include "misc.h"
|
||||
#include "systick.h"
|
||||
|
||||
#include "ccdebug.h"
|
||||
#include "pybcc3k.h"
|
||||
|
||||
// IRQ on PA14, input, pulled up, active low
|
||||
// EN on PC7, output, active high
|
||||
// CS on PC6, output, active low
|
||||
// SPI2 on PB15=MOSI, PB14=MISO, PB13=SCK
|
||||
// SCK for CC3000: max 16MHz, low when idle, data sampled on falling edge
|
||||
|
||||
// TODO this could be really wrong wrt calibration
|
||||
void pyb_delay_us(uint32_t usec) {
|
||||
volatile uint32_t count = 0;
|
||||
const uint32_t utime = (160 * usec / 5);
|
||||
do {
|
||||
if (++count > utime) {
|
||||
return;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
void pyb_cc3000_set_en(int val) {
|
||||
DEBUG_printf("pyb_cc3000_set_en val=%d\n", val);
|
||||
if (val) {
|
||||
GPIOC->BSRRL = GPIO_Pin_7; // set pin high
|
||||
} else {
|
||||
GPIOC->BSRRH = GPIO_Pin_7; // set pin low
|
||||
}
|
||||
}
|
||||
|
||||
void pyb_cc3000_set_cs(int val) {
|
||||
DEBUG_printf("pyb_cc3000_set_cs val=%d\n", val);
|
||||
if (val) {
|
||||
GPIOC->BSRRL = GPIO_Pin_6; // set pin high
|
||||
} else {
|
||||
GPIOC->BSRRH = GPIO_Pin_6; // set pin low
|
||||
}
|
||||
}
|
||||
|
||||
int pyb_cc3000_get_irq(void) {
|
||||
if ((GPIOA->IDR & GPIO_Pin_14) == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t exti14_enabled = 0; // TODO hack; do it properly!
|
||||
uint32_t exti14_missed = 0; // TODO hack; do it properly!
|
||||
|
||||
void pyb_cc3000_enable_irq(void) {
|
||||
DEBUG_printf("pyb_cc3000_enable_irq: en=%lu miss=%lu\n", exti14_enabled, exti14_missed);
|
||||
if (exti14_missed) {
|
||||
/* doesn't look like this is needed
|
||||
DEBUG_printf("pyb_cc3000_enable_irq: handling missed IRQ\n");
|
||||
// TODO hack if we have a pending IRQ
|
||||
extern void SpiIntGPIOHandler(void);
|
||||
SpiIntGPIOHandler();
|
||||
*/
|
||||
exti14_missed = 0;
|
||||
}
|
||||
exti14_enabled = 1;
|
||||
}
|
||||
|
||||
void pyb_cc3000_disable_irq(void) {
|
||||
DEBUG_printf("pyb_cc3000_disable_irq: en=%lu miss=%lu\n", exti14_enabled, exti14_missed);
|
||||
exti14_enabled = 0;
|
||||
}
|
||||
|
||||
void pyb_cc3000_pause_spi(void) {
|
||||
DEBUG_printf("pyb_cc3000_pause_spi\n");
|
||||
exti14_enabled = 0;
|
||||
}
|
||||
|
||||
void pyb_cc3000_resume_spi(void) {
|
||||
DEBUG_printf("pyb_cc3000_resume_spi\n");
|
||||
exti14_enabled = 1;
|
||||
}
|
||||
|
||||
static void EXTILine14_Config(void) {
|
||||
/* Enable SYSCFG clock */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
|
||||
|
||||
/* Configure PA14 pin as pulled-up input */
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
/* Connect EXTI Line14 to PA14 pin */
|
||||
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource14);
|
||||
|
||||
/* Configure EXTI Line14, falling edge */
|
||||
EXTI_InitTypeDef EXTI_InitStructure;
|
||||
EXTI_InitStructure.EXTI_Line = EXTI_Line14;
|
||||
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 EXTI15_10 Interrupt to the lowest priority */
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
}
|
||||
|
||||
void pyb_cc3000_spi_init(void) {
|
||||
DEBUG_printf("pyb_cc3000_spi_init\n");
|
||||
|
||||
// enable SPI clock
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
|
||||
|
||||
// GPIO clocks should already be enabled
|
||||
|
||||
/*!< SPI pins configuration *************************************************/
|
||||
|
||||
/*!< Connect SPI pins to AF5 */
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
|
||||
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;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
/*
|
||||
inf.baudRate = 100000; // FIXME - just slow for debug
|
||||
inf.spiMode = SPIF_SPI_MODE_1; // Mode 1 CPOL= 0 CPHA= 1
|
||||
*/
|
||||
|
||||
/*!< SPI configuration */
|
||||
SPI_InitTypeDef SPI_InitStructure;
|
||||
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
|
||||
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
|
||||
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // should be correct
|
||||
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // clock is low when idle
|
||||
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // data latched on second edge, which is falling edge for low-idle
|
||||
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // software control
|
||||
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; // clock freq = f_PCLK / this_prescale_value
|
||||
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // should be correct
|
||||
SPI_InitStructure.SPI_CRCPolynomial = 7; // ?
|
||||
SPI_Init(SPI2, &SPI_InitStructure);
|
||||
|
||||
/*!< Enable the SPI */
|
||||
SPI_Cmd(SPI2, ENABLE);
|
||||
|
||||
/*
|
||||
// WLAN CS, EN and WALN IRQ Configuration
|
||||
jshSetPinStateIsManual(WLAN_CS_PIN, false);
|
||||
jshPinOutput(WLAN_CS_PIN, 1); // de-assert CS
|
||||
jshSetPinStateIsManual(WLAN_EN_PIN, false);
|
||||
jshPinOutput(WLAN_EN_PIN, 0); // disable WLAN
|
||||
jshSetPinStateIsManual(WLAN_IRQ_PIN, true);
|
||||
jshPinSetState(WLAN_IRQ_PIN, JSHPINSTATE_GPIO_IN_PULLUP); // flip into read mode with pullup
|
||||
*/
|
||||
// configure wlan CS and EN pins
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
pyb_cc3000_set_cs(1); // de-assert CS
|
||||
pyb_cc3000_set_en(0); // disable wlan
|
||||
|
||||
// configure EXTI on A14
|
||||
EXTILine14_Config();
|
||||
|
||||
// wait a little (ensure that WLAN takes effect)
|
||||
sys_tick_delay_ms(500); // force a 500ms delay! FIXME
|
||||
}
|
||||
|
||||
uint8_t pyb_cc3000_spi_send(uint8_t val) {
|
||||
/*!< Loop while DR register in not emplty */
|
||||
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
|
||||
|
||||
/*!< Send byte through the SPI1 peripheral */
|
||||
SPI_I2S_SendData(SPI2, val);
|
||||
|
||||
/*!< Wait to receive a byte */
|
||||
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
|
||||
|
||||
/*!< Return the byte read from the SPI bus */
|
||||
return SPI_I2S_ReceiveData(SPI2);
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
void pyb_delay_us(uint32_t us);
|
||||
|
||||
void pyb_cc3000_set_en(int val);
|
||||
void pyb_cc3000_set_cs(int val);
|
||||
int pyb_cc3000_get_irq(void);
|
||||
void pyb_cc3000_enable_irq(void);
|
||||
void pyb_cc3000_disable_irq(void);
|
||||
void pyb_cc3000_pause_spi(void);
|
||||
void pyb_cc3000_resume_spi(void);
|
||||
|
||||
void pyb_cc3000_spi_init(void);
|
||||
uint8_t pyb_cc3000_spi_send(uint8_t val);
|
@ -1,535 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* security.c - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup security_api
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "security.h"
|
||||
|
||||
#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
|
||||
// foreward sbox
|
||||
const unsigned char sbox[256] = {
|
||||
//0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F
|
||||
// inverse sbox
|
||||
const unsigned char rsbox[256] =
|
||||
{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
|
||||
, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
|
||||
, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
|
||||
, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
|
||||
, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
|
||||
, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
|
||||
, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
|
||||
, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
|
||||
, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
|
||||
, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
|
||||
, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
|
||||
, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
|
||||
, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
|
||||
, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
|
||||
, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
|
||||
, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
|
||||
// round constant
|
||||
const unsigned char Rcon[11] = {
|
||||
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
|
||||
|
||||
|
||||
unsigned char expandedKey[176];
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! expandKey
|
||||
//!
|
||||
//! @param key AES128 key - 16 bytes
|
||||
//! @param expandedKey expanded AES128 key
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief expend a 16 bytes key for AES128 implementation
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
void expandKey(unsigned char *expandedKey,
|
||||
unsigned char *key)
|
||||
{
|
||||
unsigned short ii, buf1;
|
||||
for (ii=0;ii<16;ii++)
|
||||
expandedKey[ii] = key[ii];
|
||||
for (ii=1;ii<11;ii++){
|
||||
buf1 = expandedKey[ii*16 - 4];
|
||||
expandedKey[ii*16 + 0] = sbox[expandedKey[ii*16 - 3]]^expandedKey[(ii-1)*16 + 0]^Rcon[ii];
|
||||
expandedKey[ii*16 + 1] = sbox[expandedKey[ii*16 - 2]]^expandedKey[(ii-1)*16 + 1];
|
||||
expandedKey[ii*16 + 2] = sbox[expandedKey[ii*16 - 1]]^expandedKey[(ii-1)*16 + 2];
|
||||
expandedKey[ii*16 + 3] = sbox[buf1 ]^expandedKey[(ii-1)*16 + 3];
|
||||
expandedKey[ii*16 + 4] = expandedKey[(ii-1)*16 + 4]^expandedKey[ii*16 + 0];
|
||||
expandedKey[ii*16 + 5] = expandedKey[(ii-1)*16 + 5]^expandedKey[ii*16 + 1];
|
||||
expandedKey[ii*16 + 6] = expandedKey[(ii-1)*16 + 6]^expandedKey[ii*16 + 2];
|
||||
expandedKey[ii*16 + 7] = expandedKey[(ii-1)*16 + 7]^expandedKey[ii*16 + 3];
|
||||
expandedKey[ii*16 + 8] = expandedKey[(ii-1)*16 + 8]^expandedKey[ii*16 + 4];
|
||||
expandedKey[ii*16 + 9] = expandedKey[(ii-1)*16 + 9]^expandedKey[ii*16 + 5];
|
||||
expandedKey[ii*16 +10] = expandedKey[(ii-1)*16 +10]^expandedKey[ii*16 + 6];
|
||||
expandedKey[ii*16 +11] = expandedKey[(ii-1)*16 +11]^expandedKey[ii*16 + 7];
|
||||
expandedKey[ii*16 +12] = expandedKey[(ii-1)*16 +12]^expandedKey[ii*16 + 8];
|
||||
expandedKey[ii*16 +13] = expandedKey[(ii-1)*16 +13]^expandedKey[ii*16 + 9];
|
||||
expandedKey[ii*16 +14] = expandedKey[(ii-1)*16 +14]^expandedKey[ii*16 +10];
|
||||
expandedKey[ii*16 +15] = expandedKey[(ii-1)*16 +15]^expandedKey[ii*16 +11];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! galois_mul2
|
||||
//!
|
||||
//! @param value argument to multiply
|
||||
//!
|
||||
//! @return multiplied argument
|
||||
//!
|
||||
//! @brief multiply by 2 in the galois field
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
unsigned char galois_mul2(unsigned char value)
|
||||
{
|
||||
if (value>>7)
|
||||
{
|
||||
value = value << 1;
|
||||
return (value^0x1b);
|
||||
} else
|
||||
return value<<1;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_encr
|
||||
//!
|
||||
//! @param[in] expandedKey expanded AES128 key
|
||||
//! @param[in/out] state 16 bytes of plain text and cipher text
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief internal implementation of AES128 encryption.
|
||||
//! straight forward aes encryption implementation
|
||||
//! first the group of operations
|
||||
//! - addRoundKey
|
||||
//! - subbytes
|
||||
//! - shiftrows
|
||||
//! - mixcolums
|
||||
//! is executed 9 times, after this addroundkey to finish the 9th
|
||||
//! round, after that the 10th round without mixcolums
|
||||
//! no further subfunctions to save cycles for function calls
|
||||
//! no structuring with "for (....)" to save cycles.
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
void aes_encr(unsigned char *state, unsigned char *expandedKey)
|
||||
{
|
||||
unsigned char buf1, buf2, buf3, round;
|
||||
|
||||
for (round = 0; round < 9; round ++){
|
||||
// addroundkey, sbox and shiftrows
|
||||
// row 0
|
||||
state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])];
|
||||
state[ 4] = sbox[(state[ 4] ^ expandedKey[(round*16) + 4])];
|
||||
state[ 8] = sbox[(state[ 8] ^ expandedKey[(round*16) + 8])];
|
||||
state[12] = sbox[(state[12] ^ expandedKey[(round*16) + 12])];
|
||||
// row 1
|
||||
buf1 = state[1] ^ expandedKey[(round*16) + 1];
|
||||
state[ 1] = sbox[(state[ 5] ^ expandedKey[(round*16) + 5])];
|
||||
state[ 5] = sbox[(state[ 9] ^ expandedKey[(round*16) + 9])];
|
||||
state[ 9] = sbox[(state[13] ^ expandedKey[(round*16) + 13])];
|
||||
state[13] = sbox[buf1];
|
||||
// row 2
|
||||
buf1 = state[2] ^ expandedKey[(round*16) + 2];
|
||||
buf2 = state[6] ^ expandedKey[(round*16) + 6];
|
||||
state[ 2] = sbox[(state[10] ^ expandedKey[(round*16) + 10])];
|
||||
state[ 6] = sbox[(state[14] ^ expandedKey[(round*16) + 14])];
|
||||
state[10] = sbox[buf1];
|
||||
state[14] = sbox[buf2];
|
||||
// row 3
|
||||
buf1 = state[15] ^ expandedKey[(round*16) + 15];
|
||||
state[15] = sbox[(state[11] ^ expandedKey[(round*16) + 11])];
|
||||
state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])];
|
||||
state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])];
|
||||
state[ 3] = sbox[buf1];
|
||||
|
||||
// mixcolums //////////
|
||||
// col1
|
||||
buf1 = state[0] ^ state[1] ^ state[2] ^ state[3];
|
||||
buf2 = state[0];
|
||||
buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1;
|
||||
buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1;
|
||||
buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1;
|
||||
buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1;
|
||||
// col2
|
||||
buf1 = state[4] ^ state[5] ^ state[6] ^ state[7];
|
||||
buf2 = state[4];
|
||||
buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1;
|
||||
buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1;
|
||||
buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1;
|
||||
buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1;
|
||||
// col3
|
||||
buf1 = state[8] ^ state[9] ^ state[10] ^ state[11];
|
||||
buf2 = state[8];
|
||||
buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1;
|
||||
buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1;
|
||||
buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1;
|
||||
buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1;
|
||||
// col4
|
||||
buf1 = state[12] ^ state[13] ^ state[14] ^ state[15];
|
||||
buf2 = state[12];
|
||||
buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
|
||||
buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
|
||||
buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
|
||||
buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
|
||||
|
||||
}
|
||||
// 10th round without mixcols
|
||||
state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])];
|
||||
state[ 4] = sbox[(state[ 4] ^ expandedKey[(round*16) + 4])];
|
||||
state[ 8] = sbox[(state[ 8] ^ expandedKey[(round*16) + 8])];
|
||||
state[12] = sbox[(state[12] ^ expandedKey[(round*16) + 12])];
|
||||
// row 1
|
||||
buf1 = state[1] ^ expandedKey[(round*16) + 1];
|
||||
state[ 1] = sbox[(state[ 5] ^ expandedKey[(round*16) + 5])];
|
||||
state[ 5] = sbox[(state[ 9] ^ expandedKey[(round*16) + 9])];
|
||||
state[ 9] = sbox[(state[13] ^ expandedKey[(round*16) + 13])];
|
||||
state[13] = sbox[buf1];
|
||||
// row 2
|
||||
buf1 = state[2] ^ expandedKey[(round*16) + 2];
|
||||
buf2 = state[6] ^ expandedKey[(round*16) + 6];
|
||||
state[ 2] = sbox[(state[10] ^ expandedKey[(round*16) + 10])];
|
||||
state[ 6] = sbox[(state[14] ^ expandedKey[(round*16) + 14])];
|
||||
state[10] = sbox[buf1];
|
||||
state[14] = sbox[buf2];
|
||||
// row 3
|
||||
buf1 = state[15] ^ expandedKey[(round*16) + 15];
|
||||
state[15] = sbox[(state[11] ^ expandedKey[(round*16) + 11])];
|
||||
state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])];
|
||||
state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])];
|
||||
state[ 3] = sbox[buf1];
|
||||
// last addroundkey
|
||||
state[ 0]^=expandedKey[160];
|
||||
state[ 1]^=expandedKey[161];
|
||||
state[ 2]^=expandedKey[162];
|
||||
state[ 3]^=expandedKey[163];
|
||||
state[ 4]^=expandedKey[164];
|
||||
state[ 5]^=expandedKey[165];
|
||||
state[ 6]^=expandedKey[166];
|
||||
state[ 7]^=expandedKey[167];
|
||||
state[ 8]^=expandedKey[168];
|
||||
state[ 9]^=expandedKey[169];
|
||||
state[10]^=expandedKey[170];
|
||||
state[11]^=expandedKey[171];
|
||||
state[12]^=expandedKey[172];
|
||||
state[13]^=expandedKey[173];
|
||||
state[14]^=expandedKey[174];
|
||||
state[15]^=expandedKey[175];
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_decr
|
||||
//!
|
||||
//! @param[in] expandedKey expanded AES128 key
|
||||
//! @param[in\out] state 16 bytes of cipher text and plain text
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief internal implementation of AES128 decryption.
|
||||
//! straight forward aes decryption implementation
|
||||
//! the order of substeps is the exact reverse of decryption
|
||||
//! inverse functions:
|
||||
//! - addRoundKey is its own inverse
|
||||
//! - rsbox is inverse of sbox
|
||||
//! - rightshift instead of leftshift
|
||||
//! - invMixColumns = barreto + mixColumns
|
||||
//! no further subfunctions to save cycles for function calls
|
||||
//! no structuring with "for (....)" to save cycles
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
void aes_decr(unsigned char *state, unsigned char *expandedKey)
|
||||
{
|
||||
unsigned char buf1, buf2, buf3;
|
||||
signed char round;
|
||||
round = 9;
|
||||
|
||||
// initial addroundkey
|
||||
state[ 0]^=expandedKey[160];
|
||||
state[ 1]^=expandedKey[161];
|
||||
state[ 2]^=expandedKey[162];
|
||||
state[ 3]^=expandedKey[163];
|
||||
state[ 4]^=expandedKey[164];
|
||||
state[ 5]^=expandedKey[165];
|
||||
state[ 6]^=expandedKey[166];
|
||||
state[ 7]^=expandedKey[167];
|
||||
state[ 8]^=expandedKey[168];
|
||||
state[ 9]^=expandedKey[169];
|
||||
state[10]^=expandedKey[170];
|
||||
state[11]^=expandedKey[171];
|
||||
state[12]^=expandedKey[172];
|
||||
state[13]^=expandedKey[173];
|
||||
state[14]^=expandedKey[174];
|
||||
state[15]^=expandedKey[175];
|
||||
|
||||
// 10th round without mixcols
|
||||
state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ];
|
||||
state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4];
|
||||
state[ 8] = rsbox[state[ 8]] ^ expandedKey[(round*16) + 8];
|
||||
state[12] = rsbox[state[12]] ^ expandedKey[(round*16) + 12];
|
||||
// row 1
|
||||
buf1 = rsbox[state[13]] ^ expandedKey[(round*16) + 1];
|
||||
state[13] = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13];
|
||||
state[ 9] = rsbox[state[ 5]] ^ expandedKey[(round*16) + 9];
|
||||
state[ 5] = rsbox[state[ 1]] ^ expandedKey[(round*16) + 5];
|
||||
state[ 1] = buf1;
|
||||
// row 2
|
||||
buf1 = rsbox[state[ 2]] ^ expandedKey[(round*16) + 10];
|
||||
buf2 = rsbox[state[ 6]] ^ expandedKey[(round*16) + 14];
|
||||
state[ 2] = rsbox[state[10]] ^ expandedKey[(round*16) + 2];
|
||||
state[ 6] = rsbox[state[14]] ^ expandedKey[(round*16) + 6];
|
||||
state[10] = buf1;
|
||||
state[14] = buf2;
|
||||
// row 3
|
||||
buf1 = rsbox[state[ 3]] ^ expandedKey[(round*16) + 15];
|
||||
state[ 3] = rsbox[state[ 7]] ^ expandedKey[(round*16) + 3];
|
||||
state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7];
|
||||
state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11];
|
||||
state[15] = buf1;
|
||||
|
||||
for (round = 8; round >= 0; round--){
|
||||
// barreto
|
||||
//col1
|
||||
buf1 = galois_mul2(galois_mul2(state[0]^state[2]));
|
||||
buf2 = galois_mul2(galois_mul2(state[1]^state[3]));
|
||||
state[0] ^= buf1; state[1] ^= buf2; state[2] ^= buf1; state[3] ^= buf2;
|
||||
//col2
|
||||
buf1 = galois_mul2(galois_mul2(state[4]^state[6]));
|
||||
buf2 = galois_mul2(galois_mul2(state[5]^state[7]));
|
||||
state[4] ^= buf1; state[5] ^= buf2; state[6] ^= buf1; state[7] ^= buf2;
|
||||
//col3
|
||||
buf1 = galois_mul2(galois_mul2(state[8]^state[10]));
|
||||
buf2 = galois_mul2(galois_mul2(state[9]^state[11]));
|
||||
state[8] ^= buf1; state[9] ^= buf2; state[10] ^= buf1; state[11] ^= buf2;
|
||||
//col4
|
||||
buf1 = galois_mul2(galois_mul2(state[12]^state[14]));
|
||||
buf2 = galois_mul2(galois_mul2(state[13]^state[15]));
|
||||
state[12] ^= buf1; state[13] ^= buf2; state[14] ^= buf1; state[15] ^= buf2;
|
||||
// mixcolums //////////
|
||||
// col1
|
||||
buf1 = state[0] ^ state[1] ^ state[2] ^ state[3];
|
||||
buf2 = state[0];
|
||||
buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1;
|
||||
buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1;
|
||||
buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1;
|
||||
buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1;
|
||||
// col2
|
||||
buf1 = state[4] ^ state[5] ^ state[6] ^ state[7];
|
||||
buf2 = state[4];
|
||||
buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1;
|
||||
buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1;
|
||||
buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1;
|
||||
buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1;
|
||||
// col3
|
||||
buf1 = state[8] ^ state[9] ^ state[10] ^ state[11];
|
||||
buf2 = state[8];
|
||||
buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1;
|
||||
buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1;
|
||||
buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1;
|
||||
buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1;
|
||||
// col4
|
||||
buf1 = state[12] ^ state[13] ^ state[14] ^ state[15];
|
||||
buf2 = state[12];
|
||||
buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
|
||||
buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
|
||||
buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
|
||||
buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
|
||||
|
||||
// addroundkey, rsbox and shiftrows
|
||||
// row 0
|
||||
state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ];
|
||||
state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4];
|
||||
state[ 8] = rsbox[state[ 8]] ^ expandedKey[(round*16) + 8];
|
||||
state[12] = rsbox[state[12]] ^ expandedKey[(round*16) + 12];
|
||||
// row 1
|
||||
buf1 = rsbox[state[13]] ^ expandedKey[(round*16) + 1];
|
||||
state[13] = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13];
|
||||
state[ 9] = rsbox[state[ 5]] ^ expandedKey[(round*16) + 9];
|
||||
state[ 5] = rsbox[state[ 1]] ^ expandedKey[(round*16) + 5];
|
||||
state[ 1] = buf1;
|
||||
// row 2
|
||||
buf1 = rsbox[state[ 2]] ^ expandedKey[(round*16) + 10];
|
||||
buf2 = rsbox[state[ 6]] ^ expandedKey[(round*16) + 14];
|
||||
state[ 2] = rsbox[state[10]] ^ expandedKey[(round*16) + 2];
|
||||
state[ 6] = rsbox[state[14]] ^ expandedKey[(round*16) + 6];
|
||||
state[10] = buf1;
|
||||
state[14] = buf2;
|
||||
// row 3
|
||||
buf1 = rsbox[state[ 3]] ^ expandedKey[(round*16) + 15];
|
||||
state[ 3] = rsbox[state[ 7]] ^ expandedKey[(round*16) + 3];
|
||||
state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7];
|
||||
state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11];
|
||||
state[15] = buf1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_encrypt
|
||||
//!
|
||||
//! @param[in] key AES128 key of size 16 bytes
|
||||
//! @param[in\out] state 16 bytes of plain text and cipher text
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief AES128 encryption:
|
||||
//! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes
|
||||
//! is computed. The AES implementation is in mode ECB (Electronic
|
||||
//! Code Book).
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
void aes_encrypt(unsigned char *state,
|
||||
unsigned char *key)
|
||||
{
|
||||
// expand the key into 176 bytes
|
||||
expandKey(expandedKey, key);
|
||||
aes_encr(state, expandedKey);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_decrypt
|
||||
//!
|
||||
//! @param[in] key AES128 key of size 16 bytes
|
||||
//! @param[in\out] state 16 bytes of cipher text and plain text
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief AES128 decryption:
|
||||
//! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes
|
||||
//! is computed The AES implementation is in mode ECB
|
||||
//! (Electronic Code Book).
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
void aes_decrypt(unsigned char *state,
|
||||
unsigned char *key)
|
||||
{
|
||||
expandKey(expandedKey, key); // expand the key into 176 bytes
|
||||
aes_decr(state, expandedKey);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_read_key
|
||||
//!
|
||||
//! @param[out] key AES128 key of size 16 bytes
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Reads AES128 key from EEPROM
|
||||
//! Reads the AES128 key from fileID #12 in EEPROM
|
||||
//! returns an error if the key does not exist.
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
signed long aes_read_key(unsigned char *key)
|
||||
{
|
||||
signed long returnValue;
|
||||
|
||||
returnValue = nvmem_read(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_write_key
|
||||
//!
|
||||
//! @param[out] key AES128 key of size 16 bytes
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief writes AES128 key from EEPROM
|
||||
//! Writes the AES128 key to fileID #12 in EEPROM
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
signed long aes_write_key(unsigned char *key)
|
||||
{
|
||||
signed long returnValue;
|
||||
|
||||
returnValue = nvmem_write(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
#endif //CC3000_UNENCRYPTED_SMART_CONFIG
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
@ -1,135 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* security.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef __SECURITY__
|
||||
#define __SECURITY__
|
||||
|
||||
#include "nvmem.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define AES128_KEY_SIZE 16
|
||||
|
||||
#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_encrypt
|
||||
//!
|
||||
//! @param[in] key AES128 key of size 16 bytes
|
||||
//! @param[in\out] state 16 bytes of plain text and cipher text
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief AES128 encryption:
|
||||
//! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes
|
||||
//! is computed. The AES implementation is in mode ECB (Electronic
|
||||
//! Code Book).
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern void aes_encrypt(unsigned char *state, unsigned char *key);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_decrypt
|
||||
//!
|
||||
//! @param[in] key AES128 key of size 16 bytes
|
||||
//! @param[in\out] state 16 bytes of cipher text and plain text
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief AES128 decryption:
|
||||
//! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes
|
||||
//! is computed The AES implementation is in mode ECB
|
||||
//! (Electronic Code Book).
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern void aes_decrypt(unsigned char *state, unsigned char *key);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_read_key
|
||||
//!
|
||||
//! @param[out] key AES128 key of size 16 bytes
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Reads AES128 key from EEPROM
|
||||
//! Reads the AES128 key from fileID #12 in EEPROM
|
||||
//! returns an error if the key does not exist.
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern signed long aes_read_key(unsigned char *key);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_write_key
|
||||
//!
|
||||
//! @param[out] key AES128 key of size 16 bytes
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief writes AES128 key from EEPROM
|
||||
//! Writes the AES128 key to fileID #12 in EEPROM
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern signed long aes_write_key(unsigned char *key);
|
||||
|
||||
#endif //CC3000_UNENCRYPTED_SMART_CONFIG
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
1190
stm/cc3k/socket.c
1190
stm/cc3k/socket.c
File diff suppressed because it is too large
Load Diff
@ -1,691 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* socket.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef __SOCKET_H__
|
||||
#define __SOCKET_H__
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup socket_api
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HOSTNAME_MAX_LENGTH (230) // 230 bytes + header shouldn't exceed 8 bit value
|
||||
|
||||
//--------- Address Families --------
|
||||
|
||||
#define AF_INET 2
|
||||
#define AF_INET6 23
|
||||
|
||||
//------------ Socket Types ------------
|
||||
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
#define SOCK_RAW 3 // Raw sockets allow new IPv4 protocols to be implemented in user space. A raw socket receives or sends the raw datagram not including link level headers
|
||||
#define SOCK_RDM 4
|
||||
#define SOCK_SEQPACKET 5
|
||||
|
||||
//----------- Socket Protocol ----------
|
||||
|
||||
#define IPPROTO_IP 0 // dummy for IP
|
||||
#define IPPROTO_ICMP 1 // control message protocol
|
||||
#define IPPROTO_IPV4 IPPROTO_IP // IP inside IP
|
||||
#define IPPROTO_TCP 6 // tcp
|
||||
#define IPPROTO_UDP 17 // user datagram protocol
|
||||
#define IPPROTO_IPV6 41 // IPv6 in IPv6
|
||||
#define IPPROTO_NONE 59 // No next header
|
||||
#define IPPROTO_RAW 255 // raw IP packet
|
||||
#define IPPROTO_MAX 256
|
||||
|
||||
//----------- Socket retunr codes -----------
|
||||
|
||||
#define SOC_ERROR (-1) // error
|
||||
#define SOC_IN_PROGRESS (-2) // socket in progress
|
||||
|
||||
//----------- Socket Options -----------
|
||||
#define SOL_SOCKET 0xffff // socket level
|
||||
#define SOCKOPT_RECV_NONBLOCK 0 // recv non block mode, set SOCK_ON or SOCK_OFF (default block mode)
|
||||
#define SOCKOPT_RECV_TIMEOUT 1 // optname to configure recv and recvfromtimeout
|
||||
#define SOCKOPT_ACCEPT_NONBLOCK 2 // accept non block mode, set SOCK_ON or SOCK_OFF (default block mode)
|
||||
#define SOCK_ON 0 // socket non-blocking mode is enabled
|
||||
#define SOCK_OFF 1 // socket blocking mode is enabled
|
||||
|
||||
#define TCP_NODELAY 0x0001
|
||||
#define TCP_BSDURGENT 0x7000
|
||||
|
||||
#define MAX_PACKET_SIZE 1500
|
||||
#define MAX_LISTEN_QUEUE 4
|
||||
|
||||
#define IOCTL_SOCKET_EVENTMASK
|
||||
|
||||
#ifdef ENOBUFS
|
||||
#undef ENOBUFS
|
||||
#endif
|
||||
#define ENOBUFS 55 // No buffer space available
|
||||
|
||||
#define __FD_SETSIZE 32
|
||||
|
||||
#define ASIC_ADDR_LEN 8
|
||||
|
||||
#define NO_QUERY_RECIVED -3
|
||||
|
||||
|
||||
typedef struct _in_addr_t
|
||||
{
|
||||
unsigned long s_addr; // load with inet_aton()
|
||||
} in_addr;
|
||||
|
||||
typedef struct _sockaddr_t
|
||||
{
|
||||
unsigned short int sa_family;
|
||||
unsigned char sa_data[14];
|
||||
} sockaddr;
|
||||
|
||||
typedef struct _sockaddr_in_t
|
||||
{
|
||||
short sin_family; // e.g. AF_INET
|
||||
unsigned short sin_port; // e.g. htons(3490)
|
||||
in_addr sin_addr; // see struct in_addr, below
|
||||
char sin_zero[8]; // zero this if you want to
|
||||
} sockaddr_in;
|
||||
|
||||
typedef unsigned long socklen_t;
|
||||
|
||||
// The fd_set member is required to be an array of longs.
|
||||
typedef long int __fd_mask;
|
||||
|
||||
// It's easier to assume 8-bit bytes than to get CHAR_BIT.
|
||||
#define __NFDBITS (8 * sizeof (__fd_mask))
|
||||
#define __FDELT(d) ((d) / __NFDBITS)
|
||||
#define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS))
|
||||
|
||||
#ifdef fd_set
|
||||
#undef fd_set // for compatibility with newlib, which defines fd_set
|
||||
#endif
|
||||
|
||||
// fd_set for select and pselect.
|
||||
typedef struct
|
||||
{
|
||||
__fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
|
||||
#define __FDS_BITS(set) ((set)->fds_bits)
|
||||
} fd_set;
|
||||
|
||||
// We don't use `memset' because this would require a prototype and
|
||||
// the array isn't too big.
|
||||
#define __FD_ZERO(set) \
|
||||
do { \
|
||||
unsigned int __i; \
|
||||
fd_set *__arr = (set); \
|
||||
for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \
|
||||
__FDS_BITS (__arr)[__i] = 0; \
|
||||
} while (0)
|
||||
#define __FD_SET(d, set) (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d))
|
||||
#define __FD_CLR(d, set) (__FDS_BITS (set)[__FDELT (d)] &= ~__FDMASK (d))
|
||||
#define __FD_ISSET(d, set) (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d))
|
||||
|
||||
// Access macros for 'fd_set'.
|
||||
#ifdef FD_SET
|
||||
#undef FD_SET
|
||||
#endif
|
||||
#ifdef FD_CLR
|
||||
#undef FD_CLR
|
||||
#endif
|
||||
#ifdef FD_ISSET
|
||||
#undef FD_ISSET
|
||||
#endif
|
||||
#ifdef FD_ZERO
|
||||
#undef FD_ZERO
|
||||
#endif
|
||||
#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp)
|
||||
#define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp)
|
||||
#define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp)
|
||||
#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp)
|
||||
|
||||
//Use in case of Big Endian only
|
||||
|
||||
#define htonl(A) ((((unsigned long)(A) & 0xff000000) >> 24) | \
|
||||
(((unsigned long)(A) & 0x00ff0000) >> 8) | \
|
||||
(((unsigned long)(A) & 0x0000ff00) << 8) | \
|
||||
(((unsigned long)(A) & 0x000000ff) << 24))
|
||||
|
||||
#define ntohl htonl
|
||||
|
||||
//Use in case of Big Endian only
|
||||
#define htons(A) ((((unsigned long)(A) & 0xff00) >> 8) | \
|
||||
(((unsigned long)(A) & 0x00ff) << 8))
|
||||
|
||||
|
||||
#define ntohs htons
|
||||
|
||||
// mDNS port - 5353 mDNS multicast address - 224.0.0.251
|
||||
#define SET_mDNS_ADD(sockaddr) sockaddr.sa_data[0] = 0x14; \
|
||||
sockaddr.sa_data[1] = 0xe9; \
|
||||
sockaddr.sa_data[2] = 0xe0; \
|
||||
sockaddr.sa_data[3] = 0x0; \
|
||||
sockaddr.sa_data[4] = 0x0; \
|
||||
sockaddr.sa_data[5] = 0xfb;
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Prototypes for the APIs.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! socket
|
||||
//!
|
||||
//! @param domain selects the protocol family which will be used for
|
||||
//! communication. On this version only AF_INET is supported
|
||||
//! @param type specifies the communication semantics. On this version
|
||||
//! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported
|
||||
//! @param protocol specifies a particular protocol to be used with the
|
||||
//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are
|
||||
//! supported.
|
||||
//!
|
||||
//! @return On success, socket handle that is used for consequent socket
|
||||
//! operations. On error, -1 is returned.
|
||||
//!
|
||||
//! @brief create an endpoint for communication
|
||||
//! The socket function creates a socket that is bound to a specific
|
||||
//! transport service provider. This function is called by the
|
||||
//! application layer to obtain a socket handle.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern int socket(long domain, long type, long protocol);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! closesocket
|
||||
//!
|
||||
//! @param sd socket handle.
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned.
|
||||
//!
|
||||
//! @brief The socket function closes a created socket.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long closesocket(long sd);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! accept
|
||||
//!
|
||||
//! @param[in] sd socket descriptor (handle)
|
||||
//! @param[out] addr the argument addr is a pointer to a sockaddr structure
|
||||
//! This structure is filled in with the address of the
|
||||
//! peer socket, as known to the communications layer.
|
||||
//! determined. The exact format of the address returned
|
||||
//! addr is by the socket's address sockaddr.
|
||||
//! On this version only AF_INET is supported.
|
||||
//! This argument returns in network order.
|
||||
//! @param[out] addrlen the addrlen argument is a value-result argument:
|
||||
//! it should initially contain the size of the structure
|
||||
//! pointed to by addr.
|
||||
//!
|
||||
//! @return For socket in blocking mode:
|
||||
//! On success, socket handle. on failure negative
|
||||
//! For socket in non-blocking mode:
|
||||
//! - On connection establishment, socket handle
|
||||
//! - On connection pending, SOC_IN_PROGRESS (-2)
|
||||
//! - On failure, SOC_ERROR (-1)
|
||||
//!
|
||||
//! @brief accept a connection on a socket:
|
||||
//! This function is used with connection-based socket types
|
||||
//! (SOCK_STREAM). It extracts the first connection request on the
|
||||
//! queue of pending connections, creates a new connected socket, and
|
||||
//! returns a new file descriptor referring to that socket.
|
||||
//! The newly created socket is not in the listening state.
|
||||
//! The original socket sd is unaffected by this call.
|
||||
//! The argument sd is a socket that has been created with socket(),
|
||||
//! bound to a local address with bind(), and is listening for
|
||||
//! connections after a listen(). The argument addr is a pointer
|
||||
//! to a sockaddr structure. This structure is filled in with the
|
||||
//! address of the peer socket, as known to the communications layer.
|
||||
//! The exact format of the address returned addr is determined by the
|
||||
//! socket's address family. The addrlen argument is a value-result
|
||||
//! argument: it should initially contain the size of the structure
|
||||
//! pointed to by addr, on return it will contain the actual
|
||||
//! length (in bytes) of the address returned.
|
||||
//!
|
||||
//! @sa socket ; bind ; listen
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long accept(long sd, sockaddr *addr, socklen_t *addrlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! bind
|
||||
//!
|
||||
//! @param[in] sd socket descriptor (handle)
|
||||
//! @param[out] addr specifies the destination address. On this version
|
||||
//! only AF_INET is supported.
|
||||
//! @param[out] addrlen contains the size of the structure pointed to by addr.
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned.
|
||||
//!
|
||||
//! @brief assign a name to a socket
|
||||
//! This function gives the socket the local address addr.
|
||||
//! addr is addrlen bytes long. Traditionally, this is called when a
|
||||
//! socket is created with socket, it exists in a name space (address
|
||||
//! family) but has no name assigned.
|
||||
//! It is necessary to assign a local address before a SOCK_STREAM
|
||||
//! socket may receive connections.
|
||||
//!
|
||||
//! @sa socket ; accept ; listen
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long bind(long sd, const sockaddr *addr, long addrlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! listen
|
||||
//!
|
||||
//! @param[in] sd socket descriptor (handle)
|
||||
//! @param[in] backlog specifies the listen queue depth. On this version
|
||||
//! backlog is not supported.
|
||||
//! @return On success, zero is returned. On error, -1 is returned.
|
||||
//!
|
||||
//! @brief listen for connections on a socket
|
||||
//! The willingness to accept incoming connections and a queue
|
||||
//! limit for incoming connections are specified with listen(),
|
||||
//! and then the connections are accepted with accept.
|
||||
//! The listen() call applies only to sockets of type SOCK_STREAM
|
||||
//! The backlog parameter defines the maximum length the queue of
|
||||
//! pending connections may grow to.
|
||||
//!
|
||||
//! @sa socket ; accept ; bind
|
||||
//!
|
||||
//! @note On this version, backlog is not supported
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long listen(long sd, long backlog);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! gethostbyname
|
||||
//!
|
||||
//! @param[in] hostname host name
|
||||
//! @param[in] usNameLen name length
|
||||
//! @param[out] out_ip_addr This parameter is filled in with host IP address.
|
||||
//! In case that host name is not resolved,
|
||||
//! out_ip_addr is zero.
|
||||
//! @return On success, positive is returned. On error, negative is returned
|
||||
//!
|
||||
//! @brief Get host IP by name. Obtain the IP Address of machine on network,
|
||||
//! by its name.
|
||||
//!
|
||||
//! @note On this version, only blocking mode is supported. Also note that
|
||||
//! the function requires DNS server to be configured prior to its usage.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern int gethostbyname(const char * hostname, uint8_t usNameLen, uint32_t* out_ip_addr);
|
||||
#endif
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! connect
|
||||
//!
|
||||
//! @param[in] sd socket descriptor (handle)
|
||||
//! @param[in] addr specifies the destination addr. On this version
|
||||
//! only AF_INET is supported.
|
||||
//! @param[out] addrlen contains the size of the structure pointed to by addr
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief initiate a connection on a socket
|
||||
//! Function connects the socket referred to by the socket descriptor
|
||||
//! sd, to the address specified by addr. The addrlen argument
|
||||
//! specifies the size of addr. The format of the address in addr is
|
||||
//! determined by the address space of the socket. If it is of type
|
||||
//! SOCK_DGRAM, this call specifies the peer with which the socket is
|
||||
//! to be associated; this address is that to which datagrams are to be
|
||||
//! sent, and the only address from which datagrams are to be received.
|
||||
//! If the socket is of type SOCK_STREAM, this call attempts to make a
|
||||
//! connection to another socket. The other socket is specified by
|
||||
//! address, which is an address in the communications space of the
|
||||
//! socket. Note that the function implements only blocking behavior
|
||||
//! thus the caller will be waiting either for the connection
|
||||
//! establishment or for the connection establishment failure.
|
||||
//!
|
||||
//! @sa socket
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long connect(long sd, const sockaddr *addr, long addrlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! select
|
||||
//!
|
||||
//! @param[in] nfds the highest-numbered file descriptor in any of the
|
||||
//! three sets, plus 1.
|
||||
//! @param[out] writesds socket descriptors list for write monitoring
|
||||
//! @param[out] readsds socket descriptors list for read monitoring
|
||||
//! @param[out] exceptsds socket descriptors list for exception monitoring
|
||||
//! @param[in] timeout is an upper bound on the amount of time elapsed
|
||||
//! before select() returns. Null means infinity
|
||||
//! timeout. The minimum timeout is 5 milliseconds,
|
||||
//! less than 5 milliseconds will be set
|
||||
//! automatically to 5 milliseconds.
|
||||
//! @return On success, select() returns the number of file descriptors
|
||||
//! contained in the three returned descriptor sets (that is, the
|
||||
//! total number of bits that are set in readfds, writefds,
|
||||
//! exceptfds) which may be zero if the timeout expires before
|
||||
//! anything interesting happens.
|
||||
//! On error, -1 is returned.
|
||||
//! *readsds - return the sockets on which Read request will
|
||||
//! return without delay with valid data.
|
||||
//! *writesds - return the sockets on which Write request
|
||||
//! will return without delay.
|
||||
//! *exceptsds - return the sockets which closed recently.
|
||||
//!
|
||||
//! @brief Monitor socket activity
|
||||
//! Select allow a program to monitor multiple file descriptors,
|
||||
//! waiting until one or more of the file descriptors become
|
||||
//! "ready" for some class of I/O operation
|
||||
//!
|
||||
//! @Note If the timeout value set to less than 5ms it will automatically set
|
||||
//! to 5ms to prevent overload of the system
|
||||
//!
|
||||
//! @sa socket
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern int select(long nfds, fd_set *readsds, fd_set *writesds,
|
||||
fd_set *exceptsds, struct timeval *timeout);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! setsockopt
|
||||
//!
|
||||
//! @param[in] sd socket handle
|
||||
//! @param[in] level defines the protocol level for this option
|
||||
//! @param[in] optname defines the option name to Interrogate
|
||||
//! @param[in] optval specifies a value for the option
|
||||
//! @param[in] optlen specifies the length of the option value
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief set socket options
|
||||
//! This function manipulate the options associated with a socket.
|
||||
//! Options may exist at multiple protocol levels; they are always
|
||||
//! present at the uppermost socket level.
|
||||
//! When manipulating socket options the level at which the option
|
||||
//! resides and the name of the option must be specified.
|
||||
//! To manipulate options at the socket level, level is specified as
|
||||
//! SOL_SOCKET. To manipulate options at any other level the protocol
|
||||
//! number of the appropriate protocol controlling the option is
|
||||
//! supplied. For example, to indicate that an option is to be
|
||||
//! interpreted by the TCP protocol, level should be set to the
|
||||
//! protocol number of TCP;
|
||||
//! The parameters optval and optlen are used to access optval -
|
||||
//! use for setsockopt(). For getsockopt() they identify a buffer
|
||||
//! in which the value for the requested option(s) are to
|
||||
//! be returned. For getsockopt(), optlen is a value-result
|
||||
//! parameter, initially containing the size of the buffer
|
||||
//! pointed to by option_value, and modified on return to
|
||||
//! indicate the actual size of the value returned. If no option
|
||||
//! value is to be supplied or returned, option_value may be NULL.
|
||||
//!
|
||||
//! @Note On this version the following two socket options are enabled:
|
||||
//! The only protocol level supported in this version
|
||||
//! is SOL_SOCKET (level).
|
||||
//! 1. SOCKOPT_RECV_TIMEOUT (optname)
|
||||
//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
|
||||
//! in milliseconds.
|
||||
//! In that case optval should be pointer to unsigned long.
|
||||
//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
|
||||
//! or off.
|
||||
//! In that case optval should be SOCK_ON or SOCK_OFF (optval).
|
||||
//!
|
||||
//! @sa getsockopt
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern int setsockopt(long sd, long level, long optname, const void *optval,
|
||||
socklen_t optlen);
|
||||
#endif
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! getsockopt
|
||||
//!
|
||||
//! @param[in] sd socket handle
|
||||
//! @param[in] level defines the protocol level for this option
|
||||
//! @param[in] optname defines the option name to Interrogate
|
||||
//! @param[out] optval specifies a value for the option
|
||||
//! @param[out] optlen specifies the length of the option value
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief set socket options
|
||||
//! This function manipulate the options associated with a socket.
|
||||
//! Options may exist at multiple protocol levels; they are always
|
||||
//! present at the uppermost socket level.
|
||||
//! When manipulating socket options the level at which the option
|
||||
//! resides and the name of the option must be specified.
|
||||
//! To manipulate options at the socket level, level is specified as
|
||||
//! SOL_SOCKET. To manipulate options at any other level the protocol
|
||||
//! number of the appropriate protocol controlling the option is
|
||||
//! supplied. For example, to indicate that an option is to be
|
||||
//! interpreted by the TCP protocol, level should be set to the
|
||||
//! protocol number of TCP;
|
||||
//! The parameters optval and optlen are used to access optval -
|
||||
//! use for setsockopt(). For getsockopt() they identify a buffer
|
||||
//! in which the value for the requested option(s) are to
|
||||
//! be returned. For getsockopt(), optlen is a value-result
|
||||
//! parameter, initially containing the size of the buffer
|
||||
//! pointed to by option_value, and modified on return to
|
||||
//! indicate the actual size of the value returned. If no option
|
||||
//! value is to be supplied or returned, option_value may be NULL.
|
||||
//!
|
||||
//! @Note On this version the following two socket options are enabled:
|
||||
//! The only protocol level supported in this version
|
||||
//! is SOL_SOCKET (level).
|
||||
//! 1. SOCKOPT_RECV_TIMEOUT (optname)
|
||||
//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
|
||||
//! in milliseconds.
|
||||
//! In that case optval should be pointer to unsigned long.
|
||||
//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
|
||||
//! or off.
|
||||
//! In that case optval should be SOCK_ON or SOCK_OFF (optval).
|
||||
//!
|
||||
//! @sa setsockopt
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern int getsockopt(long sd, long level, long optname, void *optval,
|
||||
socklen_t *optlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! recv
|
||||
//!
|
||||
//! @param[in] sd socket handle
|
||||
//! @param[out] buf Points to the buffer where the message should be stored
|
||||
//! @param[in] len Specifies the length in bytes of the buffer pointed to
|
||||
//! by the buffer argument.
|
||||
//! @param[in] flags Specifies the type of message reception.
|
||||
//! On this version, this parameter is not supported.
|
||||
//!
|
||||
//! @return Return the number of bytes received, or -1 if an error
|
||||
//! occurred
|
||||
//!
|
||||
//! @brief function receives a message from a connection-mode socket
|
||||
//!
|
||||
//! @sa recvfrom
|
||||
//!
|
||||
//! @Note On this version, only blocking mode is supported.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern int recv(long sd, void *buf, long len, long flags);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! recvfrom
|
||||
//!
|
||||
//! @param[in] sd socket handle
|
||||
//! @param[out] buf Points to the buffer where the message should be stored
|
||||
//! @param[in] len Specifies the length in bytes of the buffer pointed to
|
||||
//! by the buffer argument.
|
||||
//! @param[in] flags Specifies the type of message reception.
|
||||
//! On this version, this parameter is not supported.
|
||||
//! @param[in] from pointer to an address structure indicating the source
|
||||
//! address: sockaddr. On this version only AF_INET is
|
||||
//! supported.
|
||||
//! @param[in] fromlen source address structure size
|
||||
//!
|
||||
//! @return Return the number of bytes received, or -1 if an error
|
||||
//! occurred
|
||||
//!
|
||||
//! @brief read data from socket
|
||||
//! function receives a message from a connection-mode or
|
||||
//! connectionless-mode socket. Note that raw sockets are not
|
||||
//! supported.
|
||||
//!
|
||||
//! @sa recv
|
||||
//!
|
||||
//! @Note On this version, only blocking mode is supported.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern int recvfrom(long sd, void *buf, long len, long flags, sockaddr *from,
|
||||
socklen_t *fromlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! send
|
||||
//!
|
||||
//! @param sd socket handle
|
||||
//! @param buf Points to a buffer containing the message to be sent
|
||||
//! @param len message size in bytes
|
||||
//! @param flags On this version, this parameter is not supported
|
||||
//!
|
||||
//! @return Return the number of bytes transmitted, or -1 if an
|
||||
//! error occurred
|
||||
//!
|
||||
//! @brief Write data to TCP socket
|
||||
//! This function is used to transmit a message to another
|
||||
//! socket.
|
||||
//!
|
||||
//! @Note On this version, only blocking mode is supported.
|
||||
//!
|
||||
//! @sa sendto
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern int send(long sd, const void *buf, long len, long flags);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! sendto
|
||||
//!
|
||||
//! @param sd socket handle
|
||||
//! @param buf Points to a buffer containing the message to be sent
|
||||
//! @param len message size in bytes
|
||||
//! @param flags On this version, this parameter is not supported
|
||||
//! @param to pointer to an address structure indicating the destination
|
||||
//! address: sockaddr. On this version only AF_INET is
|
||||
//! supported.
|
||||
//! @param tolen destination address structure size
|
||||
//!
|
||||
//! @return Return the number of bytes transmitted, or -1 if an
|
||||
//! error occurred
|
||||
//!
|
||||
//! @brief Write data to TCP socket
|
||||
//! This function is used to transmit a message to another
|
||||
//! socket.
|
||||
//!
|
||||
//! @Note On this version, only blocking mode is supported.
|
||||
//!
|
||||
//! @sa send
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern int sendto(long sd, const void *buf, long len, long flags,
|
||||
const sockaddr *to, socklen_t tolen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! mdnsAdvertiser
|
||||
//!
|
||||
//! @param[in] mdnsEnabled flag to enable/disable the mDNS feature
|
||||
//! @param[in] deviceServiceName Service name as part of the published
|
||||
//! canonical domain name
|
||||
//! @param[in] deviceServiceNameLength Length of the service name
|
||||
//!
|
||||
//!
|
||||
//! @return On success, zero is returned, return SOC_ERROR if socket was not
|
||||
//! opened successfully, or if an error occurred.
|
||||
//!
|
||||
//! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern int mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __SOCKET_H__
|
1264
stm/cc3k/wlan.c
1264
stm/cc3k/wlan.c
File diff suppressed because it is too large
Load Diff
533
stm/cc3k/wlan.h
533
stm/cc3k/wlan.h
@ -1,533 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* wlan.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
||||
Adapted for use with the Arduino/AVR by KTOWN for Adafruit Industries
|
||||
This library works with the Adafruit CC3000 breakout
|
||||
----> https://www.adafruit.com/products/1469
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
*****************************************************************************/
|
||||
#ifndef __WLAN_H__
|
||||
#define __WLAN_H__
|
||||
|
||||
#include "cc3000_common.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WLAN_SEC_UNSEC (0)
|
||||
#define WLAN_SEC_WEP (1)
|
||||
#define WLAN_SEC_WPA (2)
|
||||
#define WLAN_SEC_WPA2 (3)
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup wlan_api
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_init
|
||||
//!
|
||||
//! @param sWlanCB Asynchronous events callback.
|
||||
//! 0 no event call back.
|
||||
//! -call back parameters:
|
||||
//! 1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event,
|
||||
//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event,
|
||||
//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done,
|
||||
//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp report,
|
||||
//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR
|
||||
//! HCI_EVNT_WLAN_KEEPALIVE keepalive.
|
||||
//! 2) data: pointer to extra data that received by the event
|
||||
//! (NULL no data).
|
||||
//! 3) length: data length.
|
||||
//! -Events with extra data:
|
||||
//! HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask,
|
||||
//! 4 bytes default gateway, 4 bytes DHCP server and 4 bytes
|
||||
//! for DNS server.
|
||||
//! HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent,
|
||||
//! 4 bytes Packets received, 4 bytes Min round time,
|
||||
//! 4 bytes Max round time and 4 bytes for Avg round time.
|
||||
//!
|
||||
//! @param sFWPatches 0 no patch or pointer to FW patches
|
||||
//! @param sDriverPatches 0 no patch or pointer to driver patches
|
||||
//! @param sBootLoaderPatches 0 no patch or pointer to bootloader patches
|
||||
//! @param sReadWlanInterruptPin init callback. the callback read wlan
|
||||
//! interrupt status.
|
||||
//! @param sWlanInterruptEnable init callback. the callback enable wlan
|
||||
//! interrupt.
|
||||
//! @param sWlanInterruptDisable init callback. the callback disable wlan
|
||||
//! interrupt.
|
||||
//! @param sWriteWlanPin init callback. the callback write value
|
||||
//! to device pin.
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @sa wlan_set_event_mask , wlan_start , wlan_stop
|
||||
//!
|
||||
//! @brief Initialize wlan driver
|
||||
//!
|
||||
//! @warning This function must be called before ANY other wlan driver function
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void wlan_init( tWlanCB sWlanCB,
|
||||
tFWPatches sFWPatches,
|
||||
tDriverPatches sDriverPatches,
|
||||
tBootLoaderPatches sBootLoaderPatches,
|
||||
tWlanReadInteruptPin sReadWlanInterruptPin,
|
||||
tWlanInterruptEnable sWlanInterruptEnable,
|
||||
tWlanInterruptDisable sWlanInterruptDisable,
|
||||
tWriteWlanPin sWriteWlanPin);
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_start
|
||||
//!
|
||||
//! @param usPatchesAvailableAtHost - flag to indicate if patches available
|
||||
//! from host or from EEPROM. Due to the
|
||||
//! fact the patches are burn to the EEPROM
|
||||
//! using the patch programmer utility, the
|
||||
//! patches will be available from the EEPROM
|
||||
//! and not from the host.
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Start WLAN device. This function asserts the enable pin of
|
||||
//! the device (WLAN_EN), starting the HW initialization process.
|
||||
//! The function blocked until device Initialization is completed.
|
||||
//! Function also configure patches (FW, driver or bootloader)
|
||||
//! and calls appropriate device callbacks.
|
||||
//!
|
||||
//! @Note Prior calling the function wlan_init shall be called.
|
||||
//! @Warning This function must be called after wlan_init and before any
|
||||
//! other wlan API
|
||||
//! @sa wlan_init , wlan_stop
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void wlan_start(unsigned short usPatchesAvailableAtHost);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_stop
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Stop WLAN device by putting it into reset state.
|
||||
//!
|
||||
//! @sa wlan_start
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void wlan_stop(void);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_connect
|
||||
//!
|
||||
//! @param sec_type security options:
|
||||
//! WLAN_SEC_UNSEC,
|
||||
//! WLAN_SEC_WEP (ASCII support only),
|
||||
//! WLAN_SEC_WPA or WLAN_SEC_WPA2
|
||||
//! @param ssid up to 32 bytes and is ASCII SSID of the AP
|
||||
//! @param ssid_len length of the SSID
|
||||
//! @param bssid 6 bytes specified the AP bssid
|
||||
//! @param key up to 16 bytes specified the AP security key
|
||||
//! @param key_len key length
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, negative is returned.
|
||||
//! Note that even though a zero is returned on success to trigger
|
||||
//! connection operation, it does not mean that CCC3000 is already
|
||||
//! connected. An asynchronous "Connected" event is generated when
|
||||
//! actual association process finishes and CC3000 is connected to
|
||||
//! the AP. If DHCP is set, An asynchronous "DHCP" event is
|
||||
//! generated when DHCP process is finish.
|
||||
//!
|
||||
//!
|
||||
//! @brief Connect to AP
|
||||
//! @warning Please Note that when connection to AP configured with security
|
||||
//! type WEP, please confirm that the key is set as ASCII and not
|
||||
//! as HEX.
|
||||
//! @sa wlan_disconnect
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern long wlan_connect(unsigned long ulSecType, const char *ssid, long ssid_len,
|
||||
unsigned char *bssid, unsigned char *key, long key_len);
|
||||
#else
|
||||
extern long wlan_connect(const char *ssid, long ssid_len);
|
||||
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_disconnect
|
||||
//!
|
||||
//! @return 0 disconnected done, other CC3000 already disconnected
|
||||
//!
|
||||
//! @brief Disconnect connection from AP.
|
||||
//!
|
||||
//! @sa wlan_connect
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern long wlan_disconnect(void);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_add_profile
|
||||
//!
|
||||
//! @param ulSecType WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2
|
||||
//! @param ucSsid ssid SSID up to 32 bytes
|
||||
//! @param ulSsidLen ssid length
|
||||
//! @param ucBssid bssid 6 bytes
|
||||
//! @param ulPriority ulPriority profile priority. Lowest priority:0.
|
||||
//! @param ulPairwiseCipher_Or_TxKeyLen key length for WEP security
|
||||
//! @param ulGroupCipher_TxKeyIndex key index
|
||||
//! @param ulKeyMgmt KEY management
|
||||
//! @param ucPf_OrKey security key
|
||||
//! @param ulPassPhraseLen security key length for WPA\WPA2
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief When auto start is enabled, the device connects to
|
||||
//! station from the profiles table. Up to 7 profiles are supported.
|
||||
//! If several profiles configured the device choose the highest
|
||||
//! priority profile, within each priority group, device will choose
|
||||
//! profile based on security policy, signal strength, etc
|
||||
//! parameters. All the profiles are stored in CC3000 NVMEM.
|
||||
//!
|
||||
//! @sa wlan_ioctl_del_profile
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern long wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid,
|
||||
unsigned long ulSsidLen,
|
||||
unsigned char *ucBssid,
|
||||
unsigned long ulPriority,
|
||||
unsigned long ulPairwiseCipher_Or_Key,
|
||||
unsigned long ulGroupCipher_TxKeyLen,
|
||||
unsigned long ulKeyMgmt,
|
||||
unsigned char* ucPf_OrKey,
|
||||
unsigned long ulPassPhraseLen);
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_ioctl_del_profile
|
||||
//!
|
||||
//! @param index number of profile to delete
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Delete WLAN profile
|
||||
//!
|
||||
//! @Note In order to delete all stored profile, set index to 255.
|
||||
//!
|
||||
//! @sa wlan_add_profile
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_ioctl_del_profile(unsigned long ulIndex);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_set_event_mask
|
||||
//!
|
||||
//! @param mask mask option:
|
||||
//! HCI_EVNT_WLAN_UNSOL_CONNECT connect event
|
||||
//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event
|
||||
//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE smart config done
|
||||
//! HCI_EVNT_WLAN_UNSOL_INIT init done
|
||||
//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp event report
|
||||
//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report
|
||||
//! HCI_EVNT_WLAN_KEEPALIVE keepalive
|
||||
//! HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission
|
||||
//! Saved: no.
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Mask event according to bit mask. In case that event is
|
||||
//! masked (1), the device will not send the masked event to host.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_set_event_mask(unsigned long ulMask);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_ioctl_statusget
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING,
|
||||
//! STATUS_CONNECTING or WLAN_STATUS_CONNECTED
|
||||
//!
|
||||
//! @brief get wlan status: disconnected, scanning, connecting or connected
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_ioctl_statusget(void);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_ioctl_set_connection_policy
|
||||
//!
|
||||
//! @param should_connect_to_open_ap enable(1), disable(0) connect to any
|
||||
//! available AP. This parameter corresponds to the configuration of
|
||||
//! item # 3 in the brief description.
|
||||
//! @param should_use_fast_connect enable(1), disable(0). if enabled, tries
|
||||
//! to connect to the last connected AP. This parameter corresponds
|
||||
//! to the configuration of item # 1 in the brief description.
|
||||
//! @param auto_start enable(1), disable(0) auto connect
|
||||
//! after reset and periodically reconnect if needed. This
|
||||
//! configuration configures option 2 in the above description.
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief When auto is enabled, the device tries to connect according
|
||||
//! the following policy:
|
||||
//! 1) If fast connect is enabled and last connection is valid,
|
||||
//! the device will try to connect to it without the scanning
|
||||
//! procedure (fast). The last connection will be marked as
|
||||
//! invalid, due to adding/removing profile.
|
||||
//! 2) If profile exists, the device will try to connect it
|
||||
//! (Up to seven profiles).
|
||||
//! 3) If fast and profiles are not found, and open mode is
|
||||
//! enabled, the device will try to connect to any AP.
|
||||
//! * Note that the policy settings are stored in the CC3000 NVMEM.
|
||||
//!
|
||||
//! @sa wlan_add_profile , wlan_ioctl_del_profile
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_ioctl_set_connection_policy(
|
||||
unsigned long should_connect_to_open_ap,
|
||||
unsigned long should_use_fast_connect,
|
||||
unsigned long ulUseProfiles);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_ioctl_get_scan_results
|
||||
//!
|
||||
//! @param[in] scan_timeout parameter not supported
|
||||
//! @param[out] ucResults scan result (_wlan_full_scan_results_args_t)
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Gets entry from scan result table.
|
||||
//! The scan results are returned one by one, and each entry
|
||||
//! represents a single AP found in the area. The following is a
|
||||
//! format of the scan result:
|
||||
//! - 4 Bytes: number of networks found
|
||||
//! - 4 Bytes: The status of the scan: 0 - aged results,
|
||||
//! 1 - results valid, 2 - no results
|
||||
//! - 42 bytes: Result entry, where the bytes are arranged as follows:
|
||||
//!
|
||||
//! - 1 bit isValid - is result valid or not
|
||||
//! - 7 bits rssi - RSSI value;
|
||||
//! - 2 bits: securityMode - security mode of the AP:
|
||||
//! 0 - Open, 1 - WEP, 2 WPA, 3 WPA2
|
||||
//! - 6 bits: SSID name length
|
||||
//! - 2 bytes: the time at which the entry has entered into
|
||||
//! scans result table
|
||||
//! - 32 bytes: SSID name
|
||||
//! - 6 bytes: BSSID
|
||||
//!
|
||||
//! @Note scan_timeout, is not supported on this version.
|
||||
//!
|
||||
//! @sa wlan_ioctl_set_scan_params
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
extern long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout,
|
||||
unsigned char *ucResults);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_ioctl_set_scan_params
|
||||
//!
|
||||
//! @param uiEnable - start/stop application scan:
|
||||
//! 1 = start scan with default interval value of 10 min.
|
||||
//! in order to set a different scan interval value apply the value
|
||||
//! in milliseconds. minimum 1 second. 0=stop). Wlan reset
|
||||
//! (wlan_stop() wlan_start()) is needed when changing scan interval
|
||||
//! value. Saved: No
|
||||
//! @param uiMinDwellTime minimum dwell time value to be used for each
|
||||
//! channel, in milliseconds. Saved: yes
|
||||
//! Recommended Value: 100 (Default: 20)
|
||||
//! @param uiMaxDwellTime maximum dwell time value to be used for each
|
||||
//! channel, in milliseconds. Saved: yes
|
||||
//! Recommended Value: 100 (Default: 30)
|
||||
//! @param uiNumOfProbeRequests max probe request between dwell time.
|
||||
//! Saved: yes. Recommended Value: 5 (Default:2)
|
||||
//! @param uiChannelMask bitwise, up to 13 channels (0x1fff).
|
||||
//! Saved: yes. Default: 0x7ff
|
||||
//! @param uiRSSIThreshold RSSI threshold. Saved: yes (Default: -80)
|
||||
//! @param uiSNRThreshold NSR threshold. Saved: yes (Default: 0)
|
||||
//! @param uiDefaultTxPower probe Tx power. Saved: yes (Default: 205)
|
||||
//! @param aiIntervalList pointer to array with 16 entries (16 channels)
|
||||
//! each entry (unsigned long) holds timeout between periodic scan
|
||||
//! (connection scan) - in milliseconds. Saved: yes. Default 2000ms.
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief start and stop scan procedure. Set scan parameters.
|
||||
//!
|
||||
//! @Note uiDefaultTxPower, is not supported on this version.
|
||||
//!
|
||||
//! @sa wlan_ioctl_get_scan_results
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long
|
||||
uiMinDwellTime,unsigned long uiMaxDwellTime,
|
||||
unsigned long uiNumOfProbeRequests,
|
||||
unsigned long uiChannelMask,
|
||||
long iRSSIThreshold,unsigned long uiSNRThreshold,
|
||||
unsigned long uiDefaultTxPower,
|
||||
unsigned long *aiIntervalList);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_smart_config_start
|
||||
//!
|
||||
//! @param algoEncryptedFlag indicates whether the information is encrypted
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Start to acquire device profile. The device acquire its own
|
||||
//! profile, if profile message is found. The acquired AP information
|
||||
//! is stored in CC3000 EEPROM only in case AES128 encryption is used.
|
||||
//! In case AES128 encryption is not used, a profile is created by
|
||||
//! CC3000 internally.
|
||||
//!
|
||||
//! @Note An asynchronous event - Smart Config Done will be generated as soon
|
||||
//! as the process finishes successfully.
|
||||
//!
|
||||
//! @sa wlan_smart_config_set_prefix , wlan_smart_config_stop
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_smart_config_start(unsigned long algoEncryptedFlag);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_smart_config_stop
|
||||
//!
|
||||
//! @param algoEncryptedFlag indicates whether the information is encrypted
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Stop the acquire profile procedure
|
||||
//!
|
||||
//! @sa wlan_smart_config_start , wlan_smart_config_set_prefix
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_smart_config_stop(void);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_smart_config_set_prefix
|
||||
//!
|
||||
//! @param newPrefix 3 bytes identify the SSID prefix for the Smart Config.
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Configure station ssid prefix. The prefix is used internally
|
||||
//! in CC3000. It should always be TTT.
|
||||
//!
|
||||
//! @Note The prefix is stored in CC3000 NVMEM
|
||||
//!
|
||||
//! @sa wlan_smart_config_start , wlan_smart_config_stop
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_smart_config_set_prefix(char* cNewPrefix);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_smart_config_process
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief process the acquired data and store it as a profile. The acquired
|
||||
//! AP information is stored in CC3000 EEPROM encrypted.
|
||||
//! The encrypted data is decrypted and stored as a profile.
|
||||
//! behavior is as defined by connection policy.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_smart_config_process(void);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __WLAN_H__
|
1772
stm/cmsis/core_cm4.h
1772
stm/cmsis/core_cm4.h
File diff suppressed because it is too large
Load Diff
@ -1,673 +0,0 @@
|
||||
/**************************************************************************//**
|
||||
* @file core_cm4_simd.h
|
||||
* @brief CMSIS Cortex-M4 SIMD Header File
|
||||
* @version V3.20
|
||||
* @date 25. February 2013
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2009 - 2013 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __CORE_CM4_SIMD_H
|
||||
#define __CORE_CM4_SIMD_H
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/* ################### Compiler specific Intrinsics ########################### */
|
||||
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||
Access to dedicated SIMD instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
#define __SADD8 __sadd8
|
||||
#define __QADD8 __qadd8
|
||||
#define __SHADD8 __shadd8
|
||||
#define __UADD8 __uadd8
|
||||
#define __UQADD8 __uqadd8
|
||||
#define __UHADD8 __uhadd8
|
||||
#define __SSUB8 __ssub8
|
||||
#define __QSUB8 __qsub8
|
||||
#define __SHSUB8 __shsub8
|
||||
#define __USUB8 __usub8
|
||||
#define __UQSUB8 __uqsub8
|
||||
#define __UHSUB8 __uhsub8
|
||||
#define __SADD16 __sadd16
|
||||
#define __QADD16 __qadd16
|
||||
#define __SHADD16 __shadd16
|
||||
#define __UADD16 __uadd16
|
||||
#define __UQADD16 __uqadd16
|
||||
#define __UHADD16 __uhadd16
|
||||
#define __SSUB16 __ssub16
|
||||
#define __QSUB16 __qsub16
|
||||
#define __SHSUB16 __shsub16
|
||||
#define __USUB16 __usub16
|
||||
#define __UQSUB16 __uqsub16
|
||||
#define __UHSUB16 __uhsub16
|
||||
#define __SASX __sasx
|
||||
#define __QASX __qasx
|
||||
#define __SHASX __shasx
|
||||
#define __UASX __uasx
|
||||
#define __UQASX __uqasx
|
||||
#define __UHASX __uhasx
|
||||
#define __SSAX __ssax
|
||||
#define __QSAX __qsax
|
||||
#define __SHSAX __shsax
|
||||
#define __USAX __usax
|
||||
#define __UQSAX __uqsax
|
||||
#define __UHSAX __uhsax
|
||||
#define __USAD8 __usad8
|
||||
#define __USADA8 __usada8
|
||||
#define __SSAT16 __ssat16
|
||||
#define __USAT16 __usat16
|
||||
#define __UXTB16 __uxtb16
|
||||
#define __UXTAB16 __uxtab16
|
||||
#define __SXTB16 __sxtb16
|
||||
#define __SXTAB16 __sxtab16
|
||||
#define __SMUAD __smuad
|
||||
#define __SMUADX __smuadx
|
||||
#define __SMLAD __smlad
|
||||
#define __SMLADX __smladx
|
||||
#define __SMLALD __smlald
|
||||
#define __SMLALDX __smlaldx
|
||||
#define __SMUSD __smusd
|
||||
#define __SMUSDX __smusdx
|
||||
#define __SMLSD __smlsd
|
||||
#define __SMLSDX __smlsdx
|
||||
#define __SMLSLD __smlsld
|
||||
#define __SMLSLDX __smlsldx
|
||||
#define __SEL __sel
|
||||
#define __QADD __qadd
|
||||
#define __QSUB __qsub
|
||||
|
||||
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
|
||||
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
|
||||
|
||||
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
|
||||
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
|
||||
|
||||
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
|
||||
((int64_t)(ARG3) << 32) ) >> 32))
|
||||
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||
/* TI CCS specific functions */
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __SSAT16(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
#define __USAT16(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __SMLALD(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
#define __SMLALDX(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __SMLSLD(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
#define __SMLSLDX(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __PKHBT(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
#define __PKHTB(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||
if (ARG3 == 0) \
|
||||
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
|
||||
else \
|
||||
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
|
||||
{
|
||||
int32_t result;
|
||||
|
||||
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
/* not yet supported */
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||
|
||||
|
||||
#endif /* __CORE_CM4_SIMD_H */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,636 +0,0 @@
|
||||
/**************************************************************************//**
|
||||
* @file core_cmFunc.h
|
||||
* @brief CMSIS Cortex-M Core Function Access Header File
|
||||
* @version V3.20
|
||||
* @date 25. February 2013
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2009 - 2013 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __CORE_CMFUNC_H
|
||||
#define __CORE_CMFUNC_H
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
/** \ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
/* intrinsic void __enable_irq(); */
|
||||
/* intrinsic void __disable_irq(); */
|
||||
|
||||
/** \brief Get Control Register
|
||||
|
||||
This function returns the content of the Control Register.
|
||||
|
||||
\return Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
return(__regControl);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Control Register
|
||||
|
||||
This function writes the given value to the Control Register.
|
||||
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
__regControl = control;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get IPSR Register
|
||||
|
||||
This function returns the content of the IPSR Register.
|
||||
|
||||
\return IPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
register uint32_t __regIPSR __ASM("ipsr");
|
||||
return(__regIPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get APSR Register
|
||||
|
||||
This function returns the content of the APSR Register.
|
||||
|
||||
\return APSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
register uint32_t __regAPSR __ASM("apsr");
|
||||
return(__regAPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get xPSR Register
|
||||
|
||||
This function returns the content of the xPSR Register.
|
||||
|
||||
\return xPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
register uint32_t __regXPSR __ASM("xpsr");
|
||||
return(__regXPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Process Stack Pointer
|
||||
|
||||
This function returns the current value of the Process Stack Pointer (PSP).
|
||||
|
||||
\return PSP Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
return(__regProcessStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
|
||||
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
__regProcessStackPointer = topOfProcStack;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Main Stack Pointer
|
||||
|
||||
This function returns the current value of the Main Stack Pointer (MSP).
|
||||
|
||||
\return MSP Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
return(__regMainStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Main Stack Pointer
|
||||
|
||||
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
__regMainStackPointer = topOfMainStack;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Priority Mask
|
||||
|
||||
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
|
||||
\return Priority Mask value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
return(__regPriMask);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Priority Mask
|
||||
|
||||
This function assigns the given value to the Priority Mask Register.
|
||||
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
__regPriMask = (priMask);
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Enable FIQ
|
||||
|
||||
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
|
||||
|
||||
/** \brief Disable FIQ
|
||||
|
||||
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __disable_fault_irq __disable_fiq
|
||||
|
||||
|
||||
/** \brief Get Base Priority
|
||||
|
||||
This function returns the current value of the Base Priority register.
|
||||
|
||||
\return Base Priority register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
return(__regBasePri);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Base Priority
|
||||
|
||||
This function assigns the given value to the Base Priority register.
|
||||
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
__regBasePri = (basePri & 0xff);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Fault Mask
|
||||
|
||||
This function returns the current value of the Fault Mask register.
|
||||
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
return(__regFaultMask);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Fault Mask
|
||||
|
||||
This function assigns the given value to the Fault Mask register.
|
||||
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
__regFaultMask = (faultMask & (uint32_t)1);
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
#if (__CORTEX_M == 0x04)
|
||||
|
||||
/** \brief Get FPSCR
|
||||
|
||||
This function returns the current value of the Floating Point Status/Control register.
|
||||
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
return(__regfpscr);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set FPSCR
|
||||
|
||||
This function assigns the given value to the Floating Point Status/Control register.
|
||||
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
__regfpscr = (fpscr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M == 0x04) */
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
|
||||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||
/* TI CCS specific functions */
|
||||
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/** \brief Enable IRQ Interrupts
|
||||
|
||||
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsie i" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Disable IRQ Interrupts
|
||||
|
||||
This function disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsid i" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Control Register
|
||||
|
||||
This function returns the content of the Control Register.
|
||||
|
||||
\return Control Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, control" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Control Register
|
||||
|
||||
This function writes the given value to the Control Register.
|
||||
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get IPSR Register
|
||||
|
||||
This function returns the content of the IPSR Register.
|
||||
|
||||
\return IPSR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get APSR Register
|
||||
|
||||
This function returns the content of the APSR Register.
|
||||
|
||||
\return APSR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get xPSR Register
|
||||
|
||||
This function returns the content of the xPSR Register.
|
||||
|
||||
\return xPSR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Process Stack Pointer
|
||||
|
||||
This function returns the current value of the Process Stack Pointer (PSP).
|
||||
|
||||
\return PSP Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
|
||||
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Main Stack Pointer
|
||||
|
||||
This function returns the current value of the Main Stack Pointer (MSP).
|
||||
|
||||
\return MSP Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Main Stack Pointer
|
||||
|
||||
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Priority Mask
|
||||
|
||||
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
|
||||
\return Priority Mask value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, primask" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Priority Mask
|
||||
|
||||
This function assigns the given value to the Priority Mask Register.
|
||||
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
__ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Enable FIQ
|
||||
|
||||
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsie f" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Disable FIQ
|
||||
|
||||
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsid f" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Base Priority
|
||||
|
||||
This function returns the current value of the Base Priority register.
|
||||
|
||||
\return Base Priority register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Base Priority
|
||||
|
||||
This function assigns the given value to the Base Priority register.
|
||||
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Fault Mask
|
||||
|
||||
This function returns the current value of the Fault Mask register.
|
||||
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Fault Mask
|
||||
|
||||
This function assigns the given value to the Fault Mask register.
|
||||
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
#if (__CORTEX_M == 0x04)
|
||||
|
||||
/** \brief Get FPSCR
|
||||
|
||||
This function returns the current value of the Floating Point Status/Control register.
|
||||
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
uint32_t result;
|
||||
|
||||
/* Empty asm statement works as a scheduling barrier */
|
||||
__ASM volatile ("");
|
||||
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
|
||||
__ASM volatile ("");
|
||||
return(result);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set FPSCR
|
||||
|
||||
This function assigns the given value to the Floating Point Status/Control register.
|
||||
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
/* Empty asm statement works as a scheduling barrier */
|
||||
__ASM volatile ("");
|
||||
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
|
||||
__ASM volatile ("");
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M == 0x04) */
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all instrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||
|
||||
|
||||
#endif /* __CORE_CMFUNC_H */
|
@ -1,688 +0,0 @@
|
||||
/**************************************************************************//**
|
||||
* @file core_cmInstr.h
|
||||
* @brief CMSIS Cortex-M Core Instruction Access Header File
|
||||
* @version V3.20
|
||||
* @date 05. March 2013
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2009 - 2013 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __CORE_CMINSTR_H
|
||||
#define __CORE_CMINSTR_H
|
||||
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||
Access to dedicated instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
#define __NOP __nop
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFI __wfi
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFE __wfe
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
#define __SEV __sev
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
#define __ISB() __isb(0xF)
|
||||
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
#define __DSB() __dsb(0xF)
|
||||
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
#define __DMB() __dmb(0xF)
|
||||
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __rev
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief Rotate Right in unsigned value (32 bit)
|
||||
|
||||
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\param [in] value Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#define __ROR __ror
|
||||
|
||||
|
||||
/** \brief Breakpoint
|
||||
|
||||
This function causes the processor to enter Debug state.
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __breakpoint(value)
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __RBIT __rbit
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive STR command for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive STR command for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive STR command for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
#define __CLREX __clrex
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __ssat
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __usat
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __clz
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
|
||||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||
/* TI CCS specific functions */
|
||||
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/* Define macros for porting to both thumb1 and thumb2.
|
||||
* For thumb1, use low register (r0-r7), specified by constrant "l"
|
||||
* Otherwise, use general registers, specified by constrant "r" */
|
||||
#if defined (__thumb__) && !defined (__thumb2__)
|
||||
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
|
||||
#define __CMSIS_GCC_USE_REG(r) "l" (r)
|
||||
#else
|
||||
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
|
||||
#define __CMSIS_GCC_USE_REG(r) "r" (r)
|
||||
#endif
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
|
||||
{
|
||||
__ASM volatile ("wfi");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
|
||||
{
|
||||
__ASM volatile ("wfe");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
|
||||
{
|
||||
__ASM volatile ("sev");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
|
||||
{
|
||||
__ASM volatile ("isb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
|
||||
{
|
||||
__ASM volatile ("dsb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
|
||||
{
|
||||
__ASM volatile ("dmb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||
return __builtin_bswap32(value);
|
||||
#else
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
|
||||
{
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
return (short)__builtin_bswap16(value);
|
||||
#else
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Rotate Right in unsigned value (32 bit)
|
||||
|
||||
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\param [in] value Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
return (op1 >> op2) | (op1 << (32 - op2));
|
||||
}
|
||||
|
||||
|
||||
/** \brief Breakpoint
|
||||
|
||||
This function causes the processor to enter Debug state.
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive STR command for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive STR command for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive STR command for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
|
||||
{
|
||||
__ASM volatile ("clrex" ::: "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||
|
||||
#endif /* __CORE_CMINSTR_H */
|
28
stm/delay.s
28
stm/delay.s
@ -1,28 +0,0 @@
|
||||
.syntax unified
|
||||
.cpu cortex-m4
|
||||
.thumb
|
||||
.text
|
||||
.align 2
|
||||
.global delay_ms
|
||||
.thumb
|
||||
.thumb_func
|
||||
.type delay_ms, %function
|
||||
@ void delay_ms(int ms)
|
||||
delay_ms:
|
||||
@ r0 is argument, trashes r2, r3
|
||||
adds r3, r0, #0
|
||||
b .L2
|
||||
.L5:
|
||||
movw r2, #55999
|
||||
b .L3
|
||||
.L4:
|
||||
subs r2, r2, #1
|
||||
.L3:
|
||||
cmp r2, #0
|
||||
bgt .L4
|
||||
subs r3, r3, #1
|
||||
.L2:
|
||||
cmp r3, #0
|
||||
bgt .L5
|
||||
bx lr
|
||||
.size delay_ms, .-delay_ms
|
432
stm/exti.c
432
stm/exti.c
@ -1,432 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_gpio.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "nlr.h"
|
||||
|
||||
#include "pin.h"
|
||||
#include "exti.h"
|
||||
|
||||
// Usage Model:
|
||||
//
|
||||
// There are a total of 22 interrupt lines. 16 of these can come from GPIO pins
|
||||
// and the remaining 6 are from internal sources.
|
||||
//
|
||||
// For lines 0 thru 15, a given line can map to the corresponding line from an
|
||||
// arbitrary port. So line 0 can map to Px0 where x is A, B, C, ... and
|
||||
// line 1 can map to Px1 where x is A, B, C, ...
|
||||
//
|
||||
// def callback(line):
|
||||
// print("line =", line)
|
||||
//
|
||||
// # Configure the pin as a GPIO input.
|
||||
// pin = pyb.Pin.board.X1
|
||||
// pyb.gpio_in(pin, pyb.PULL_UP)
|
||||
// exti = pyb.Exti(pin, pyb.Exti.MODE_IRQ, pyb.Exti.TRIGGER_RISING, callback, 37)
|
||||
//
|
||||
// Now every time a rising edge is seen on the X1 pin, the callback will be
|
||||
// called. Caution: mechanical pushbuttons have "bounce" and pushing or
|
||||
// releasing a switch will often generate multiple edges.
|
||||
// See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed
|
||||
// explanation, along with various techniques for debouncing.
|
||||
//
|
||||
// Trying to register 2 callbacks onto the same pin will throw an exception.
|
||||
//
|
||||
// If pin is passed as an integer, then it is assumed to map to one of the
|
||||
// internal interrupt sources, and must be in the range 16 thru 22.
|
||||
//
|
||||
// All other pin objects go through the pin mapper to come up with one of the
|
||||
// gpio pins.
|
||||
//
|
||||
// Valid modes are pyb.Exti.MODE_IRQ and pyb.Exti.MODE_EVENT (Only MODE_IRQ
|
||||
// has been tested. MODE_EVENT has something to do with sleep mode and the
|
||||
// WFE instruction).
|
||||
//
|
||||
// Valid edge triggers are pyb.Exti.TRIGGER_RISING, TRIGGER_FALLING, and TRIGGER_BOTH.
|
||||
//
|
||||
// exti.line() will return the line number that pin was mapped to.
|
||||
// exti.disable() can be use to disable the interrupt associated with a given
|
||||
// exti object. This could be useful for debouncing.
|
||||
// exti.enable() enables a disabled interrupt
|
||||
// exti.swint() will allow the callback to be triggered from software.
|
||||
//
|
||||
// pyb.Exti.regs() will dump the values of the EXTI registers.
|
||||
//
|
||||
// There is also a C API, so that drivers which require EXTI interrupt lines
|
||||
// can also use this code. See exti.h for the available functions and
|
||||
// usrsw.h for an example of using this.
|
||||
|
||||
#define EXTI_OFFSET (EXTI_BASE - PERIPH_BASE)
|
||||
|
||||
// Macro used to set/clear the bit corresponding to the line in the IMR/EMR
|
||||
// register in an atomic fashion by using bitband addressing.
|
||||
#define EXTI_MODE_BB(mode, line) (*(vu32 *)(PERIPH_BB_BASE + ((EXTI_OFFSET + (mode)) * 32) + ((line) * 4)))
|
||||
|
||||
// This macro will work with the EXTI_Trigger_Rising and EXTI_Trigger_Falling constants
|
||||
// but not EXTI_Trigger_Rising_Falling.
|
||||
#define EXTI_EDGE_BB(edge, line) (*(vu32 *)(PERIPH_BB_BASE + ((EXTI_OFFSET + (edge)) * 32) + ((line) * 4)))
|
||||
|
||||
#define EXTI_SWIER_BB(line) (*(vu32 *)(PERIPH_BB_BASE + ((EXTI_OFFSET + offsetof(EXTI_TypeDef, SWIER)) * 32) + ((line) * 4)))
|
||||
#define EXTI_PR_BB(line) (*(vu32 *)(PERIPH_BB_BASE + ((EXTI_OFFSET + offsetof(EXTI_TypeDef, PR)) * 32) + ((line) * 4)))
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
mp_small_int_t line;
|
||||
} exti_obj_t;
|
||||
|
||||
typedef struct {
|
||||
mp_obj_t callback_obj;
|
||||
void *param;
|
||||
EXTIMode_TypeDef mode;
|
||||
} exti_vector_t;
|
||||
|
||||
static exti_vector_t exti_vector[EXTI_NUM_VECTORS];
|
||||
|
||||
static const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = {
|
||||
EXTI0_IRQn, EXTI1_IRQn, EXTI2_IRQn, EXTI3_IRQn, EXTI4_IRQn,
|
||||
EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn,
|
||||
EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn,
|
||||
EXTI15_10_IRQn, PVD_IRQn, RTC_Alarm_IRQn, OTG_FS_WKUP_IRQn, ETH_WKUP_IRQn,
|
||||
OTG_HS_WKUP_IRQn, TAMP_STAMP_IRQn, RTC_WKUP_IRQn
|
||||
};
|
||||
|
||||
// NOTE: param is for C callers. Python can use closure to get an object bound
|
||||
// with the function.
|
||||
uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t trigger_obj, mp_obj_t callback_obj, void *param) {
|
||||
const pin_obj_t *pin = NULL;
|
||||
uint v_line;
|
||||
|
||||
if (MP_OBJ_IS_INT(pin_obj)) {
|
||||
// If an integer is passed in, then use it to identify lines 16 thru 22
|
||||
// We expect lines 0 thru 15 to be passed in as a pin, so that we can
|
||||
// get both the port number and line number.
|
||||
v_line = mp_obj_get_int(pin_obj);
|
||||
if (v_line < 16) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "EXTI vector %d < 16, use a Pin object", v_line));
|
||||
}
|
||||
if (v_line >= EXTI_NUM_VECTORS) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "EXTI vector %d >= max of %d", v_line, EXTI_NUM_VECTORS));
|
||||
}
|
||||
} else {
|
||||
pin = pin_map_user_obj(pin_obj);
|
||||
v_line = pin->pin;
|
||||
}
|
||||
int mode = mp_obj_get_int(mode_obj);
|
||||
if (!IS_EXTI_MODE(mode)) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Invalid EXTI Mode: %d", mode));
|
||||
}
|
||||
int trigger = mp_obj_get_int(trigger_obj);
|
||||
if (!IS_EXTI_TRIGGER(trigger)) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Invalid EXTI Trigger: %d", trigger));
|
||||
}
|
||||
|
||||
exti_vector_t *v = &exti_vector[v_line];
|
||||
if (v->callback_obj != mp_const_none && callback_obj != mp_const_none) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "EXTI vector %d is already in use", v_line));
|
||||
}
|
||||
|
||||
// We need to update callback and param atomically, so we disable the line
|
||||
// before we update anything.
|
||||
|
||||
exti_disable(v_line);
|
||||
|
||||
if (pin && callback_obj) {
|
||||
// Enable SYSCFG clock
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
|
||||
|
||||
// For EXTI lines 0 thru 15, we need to configure which port controls
|
||||
// the line.
|
||||
SYSCFG_EXTILineConfig(pin->port, v_line);
|
||||
}
|
||||
v->callback_obj = callback_obj;
|
||||
v->param = param;
|
||||
v->mode = mode;
|
||||
|
||||
if (v->callback_obj != mp_const_none) {
|
||||
// The EXTI_Init function isn't atomic. It uses |= and &=.
|
||||
// We use bit band operations to make it atomic.
|
||||
EXTI_EDGE_BB(EXTI_Trigger_Rising, v_line) =
|
||||
trigger == EXTI_Trigger_Rising || trigger == EXTI_Trigger_Rising_Falling;
|
||||
EXTI_EDGE_BB(EXTI_Trigger_Falling, v_line) =
|
||||
trigger == EXTI_Trigger_Falling || trigger == EXTI_Trigger_Rising_Falling;
|
||||
exti_enable(v_line);
|
||||
|
||||
/* Enable and set NVIC Interrupt to the lowest priority */
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
NVIC_InitStructure.NVIC_IRQChannel = nvic_irq_channel[v_line];
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
}
|
||||
return v_line;
|
||||
}
|
||||
|
||||
void exti_enable(uint line) {
|
||||
if (line >= EXTI_NUM_VECTORS) {
|
||||
return;
|
||||
}
|
||||
// Since manipulating IMR/EMR is a read-modify-write, and we want this to
|
||||
// be atomic, we use the bit-band area to just affect the bit we're
|
||||
// interested in.
|
||||
EXTI_MODE_BB(exti_vector[line].mode, line) = 1;
|
||||
}
|
||||
|
||||
void exti_disable(uint line) {
|
||||
if (line >= EXTI_NUM_VECTORS) {
|
||||
return;
|
||||
}
|
||||
// Since manipulating IMR/EMR is a read-modify-write, and we want this to
|
||||
// be atomic, we use the bit-band area to just affect the bit we're
|
||||
// interested in.
|
||||
EXTI_MODE_BB(EXTI_Mode_Interrupt, line) = 0;
|
||||
EXTI_MODE_BB(EXTI_Mode_Event, line) = 0;
|
||||
}
|
||||
|
||||
void exti_swint(uint line) {
|
||||
if (line >= EXTI_NUM_VECTORS) {
|
||||
return;
|
||||
}
|
||||
EXTI_SWIER_BB(line) = 1;
|
||||
}
|
||||
|
||||
static mp_obj_t exti_obj_line(mp_obj_t self_in) {
|
||||
exti_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_SMALL_INT(self->line);
|
||||
}
|
||||
|
||||
static mp_obj_t exti_obj_enable(mp_obj_t self_in) {
|
||||
exti_obj_t *self = self_in;
|
||||
exti_enable(self->line);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static mp_obj_t exti_obj_disable(mp_obj_t self_in) {
|
||||
exti_obj_t *self = self_in;
|
||||
exti_disable(self->line);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static mp_obj_t exti_obj_swint(mp_obj_t self_in) {
|
||||
exti_obj_t *self = self_in;
|
||||
exti_swint(self->line);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(exti_obj_line_obj, exti_obj_line);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(exti_obj_enable_obj, exti_obj_enable);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(exti_obj_disable_obj, exti_obj_disable);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(exti_obj_swint_obj, exti_obj_swint);
|
||||
|
||||
STATIC const mp_map_elem_t exti_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_line), (mp_obj_t) &exti_obj_line_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t) &exti_obj_enable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t) &exti_obj_disable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_swint), (mp_obj_t) &exti_obj_swint_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(exti_locals_dict, exti_locals_dict_table);
|
||||
|
||||
static mp_obj_t exti_regs(void) {
|
||||
printf("EXTI_IMR %08lx\n", EXTI->IMR);
|
||||
printf("EXTI_EMR %08lx\n", EXTI->EMR);
|
||||
printf("EXTI_RTSR %08lx\n", EXTI->RTSR);
|
||||
printf("EXTI_FTSR %08lx\n", EXTI->FTSR);
|
||||
printf("EXTI_SWIER %08lx\n", EXTI->SWIER);
|
||||
printf("EXTI_PR %08lx\n", EXTI->PR);
|
||||
return mp_const_none;
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_0(exti_regs_obj, exti_regs);
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
uint val;
|
||||
} exti_const_t;
|
||||
|
||||
static const exti_const_t exti_const[] = {
|
||||
{ "MODE_IRQ", EXTI_Mode_Interrupt },
|
||||
{ "MODE_EVENT", EXTI_Mode_Event },
|
||||
{ "TRIGGER_RISING", EXTI_Trigger_Rising },
|
||||
{ "TRIGGER_FALLING", EXTI_Trigger_Falling },
|
||||
{ "TRIGGER_BOTH", EXTI_Trigger_Rising_Falling },
|
||||
};
|
||||
#define EXTI_NUM_CONST (sizeof(exti_const) / sizeof(exti_const[0]))
|
||||
|
||||
static void exti_load_attr(mp_obj_t self_in, qstr attr_qstr, mp_obj_t *dest) {
|
||||
(void)self_in;
|
||||
const char *attr = qstr_str(attr_qstr);
|
||||
|
||||
if (strcmp(attr, "regs") == 0) {
|
||||
dest[0] = (mp_obj_t)&exti_regs_obj;
|
||||
return;
|
||||
}
|
||||
const exti_const_t *entry = &exti_const[0];
|
||||
for (; entry < &exti_const[EXTI_NUM_CONST]; entry++) {
|
||||
if (strcmp(attr, entry->name) == 0) {
|
||||
dest[0] = MP_OBJ_NEW_SMALL_INT(entry->val);
|
||||
dest[1] = MP_OBJ_NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// line_obj = pyb.Exti(pin, mode, trigger, callback)
|
||||
|
||||
static mp_obj_t exti_call(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
|
||||
// type_in == exti_obj_type
|
||||
|
||||
mp_arg_check_num(n_args, n_kw, 4, 4, 0);
|
||||
|
||||
exti_obj_t *self = m_new_obj(exti_obj_t);
|
||||
self->base.type = type_in;
|
||||
mp_obj_t line_obj = args[0];
|
||||
mp_obj_t mode_obj = args[1];
|
||||
mp_obj_t trigger_obj = args[2];
|
||||
mp_obj_t callback_obj = args[3];
|
||||
self->line = exti_register(line_obj, mode_obj, trigger_obj, callback_obj, NULL);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static void exti_meta_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void) self_in;
|
||||
print(env, "<Exti meta>");
|
||||
}
|
||||
|
||||
static void exti_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
exti_obj_t *self = self_in;
|
||||
print(env, "<Exti line=%u>", self->line);
|
||||
}
|
||||
|
||||
static const mp_obj_type_t exti_meta_obj_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_ExtiMeta,
|
||||
.print = exti_meta_obj_print,
|
||||
.call = exti_call,
|
||||
.load_attr = exti_load_attr,
|
||||
};
|
||||
|
||||
const mp_obj_type_t exti_obj_type = {
|
||||
{ &exti_meta_obj_type },
|
||||
.name = MP_QSTR_Exti,
|
||||
.print = exti_obj_print,
|
||||
.locals_dict = (mp_obj_t)&exti_locals_dict,
|
||||
};
|
||||
|
||||
void exti_init(void) {
|
||||
for (exti_vector_t *v = exti_vector; v < &exti_vector[EXTI_NUM_VECTORS]; v++) {
|
||||
v->callback_obj = mp_const_none;
|
||||
v->param = NULL;
|
||||
v->mode = EXTI_Mode_Interrupt;
|
||||
}
|
||||
}
|
||||
|
||||
static void Handle_EXTI_Irq(uint32_t line) {
|
||||
if (EXTI_PR_BB(line)) {
|
||||
EXTI_PR_BB(line) = 1; // Clears bit
|
||||
if (line < EXTI_NUM_VECTORS) {
|
||||
exti_vector_t *v = &exti_vector[line];
|
||||
if (v->callback_obj != mp_const_none) {
|
||||
mp_call_function_1(v->callback_obj, MP_OBJ_NEW_SMALL_INT(line));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EXTI0_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(0);
|
||||
}
|
||||
|
||||
void EXTI1_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(1);
|
||||
}
|
||||
|
||||
void EXTI2_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(2);
|
||||
}
|
||||
|
||||
void EXTI3_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(3);
|
||||
}
|
||||
|
||||
void EXTI4_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(4);
|
||||
}
|
||||
|
||||
void EXTI9_5_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(5);
|
||||
Handle_EXTI_Irq(6);
|
||||
Handle_EXTI_Irq(7);
|
||||
Handle_EXTI_Irq(8);
|
||||
Handle_EXTI_Irq(9);
|
||||
}
|
||||
|
||||
void EXTI15_10_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(10);
|
||||
Handle_EXTI_Irq(11);
|
||||
Handle_EXTI_Irq(12);
|
||||
Handle_EXTI_Irq(13);
|
||||
Handle_EXTI_Irq(14);
|
||||
Handle_EXTI_Irq(15);
|
||||
|
||||
#if 0
|
||||
// for CC3000 support, needs to be re-written to use new EXTI code
|
||||
if (EXTI_GetITStatus(EXTI_Line14) != RESET) {
|
||||
led_toggle(PYB_LED_G2);
|
||||
/* these are needed for CC3000 support
|
||||
extern void SpiIntGPIOHandler(void);
|
||||
extern uint32_t exti14_enabled;
|
||||
extern uint32_t exti14_missed;
|
||||
//printf("-> EXTI14 en=%lu miss=%lu\n", exti14_enabled, exti14_missed);
|
||||
if (exti14_enabled) {
|
||||
exti14_missed = 0;
|
||||
SpiIntGPIOHandler(); // CC3000 interrupt
|
||||
} else {
|
||||
exti14_missed = 1;
|
||||
}
|
||||
*/
|
||||
EXTI_ClearITPendingBit(EXTI_Line14);
|
||||
//printf("<- EXTI14 done\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void PVD_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(16);
|
||||
}
|
||||
|
||||
void RTC_Alarm_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(17);
|
||||
}
|
||||
|
||||
#if 0 // dealt with in stm32fxxx_it.c
|
||||
void OTG_FS_WKUP_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(18);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ETH_WKUP_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(19);
|
||||
}
|
||||
|
||||
#if 0 // dealt with in stm32fxxx_it.c
|
||||
void OTG_HS_WKUP_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(20);
|
||||
}
|
||||
#endif
|
||||
|
||||
void TAMP_STAMP_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(21);
|
||||
}
|
||||
|
||||
void RTC_WKUP_IRQHandler(void) {
|
||||
Handle_EXTI_Irq(22);
|
||||
}
|
29
stm/exti.h
29
stm/exti.h
@ -1,29 +0,0 @@
|
||||
// Vectors 0-15 are for regular pins
|
||||
// Vectors 16-22 are for internal sources.
|
||||
//
|
||||
// Use the following constants for the internal sources:
|
||||
|
||||
#define EXTI_PVD_OUTPUT (16)
|
||||
#define EXTI_RTC_ALARM (17)
|
||||
#define EXTI_USB_OTG_FS_WAKEUP (18)
|
||||
#define EXTI_ETH_WAKEUP (19)
|
||||
#define EXTI_USB_OTG_HS_WAKEUP (20)
|
||||
#define EXTI_RTC_TIMESTAMP (21)
|
||||
#define EXTI_RTC_WAKEUP (22)
|
||||
|
||||
#define EXTI_NUM_VECTORS 23
|
||||
|
||||
void exti_init(void);
|
||||
|
||||
uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t trigger_obj, mp_obj_t callback_obj, void *param);
|
||||
|
||||
void exti_enable(uint line);
|
||||
void exti_disable(uint line);
|
||||
void exti_swint(uint line);
|
||||
|
||||
typedef struct {
|
||||
mp_obj_t callback;
|
||||
void *param;
|
||||
} exti_t;
|
||||
|
||||
extern const mp_obj_type_t exti_obj_type;
|
@ -1,147 +0,0 @@
|
||||
FatFs Module Source Files R0.10 (C)ChaN, 2013
|
||||
|
||||
|
||||
FILES
|
||||
|
||||
ffconf.h Configuration file for FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
ff.c FatFs module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
integer.h Integer type definitions for FatFs.
|
||||
option Optional external functions.
|
||||
|
||||
Low level disk I/O module is not included in this archive because the FatFs
|
||||
module is only a generic file system layer and not depend on any specific
|
||||
storage device. You have to provide a low level disk I/O module that written
|
||||
to control your storage device.
|
||||
|
||||
|
||||
|
||||
AGREEMENTS
|
||||
|
||||
FatFs module is an open source software to implement FAT file system to
|
||||
small embedded systems. This is a free software and is opened for education,
|
||||
research and commercial developments under license policy of following trems.
|
||||
|
||||
Copyright (C) 2013, ChaN, all right reserved.
|
||||
|
||||
* The FatFs module is a free software and there is NO WARRANTY.
|
||||
* No restriction on use. You can use, modify and redistribute it for
|
||||
personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
|
||||
* Redistributions of source code must retain the above copyright notice.
|
||||
|
||||
|
||||
|
||||
REVISION HISTORY
|
||||
|
||||
Feb 26, 2006 R0.00 Prototype
|
||||
|
||||
Apr 29, 2006 R0.01 First release.
|
||||
|
||||
Jun 01, 2006 R0.02 Added FAT12.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) patition.
|
||||
|
||||
Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM.
|
||||
|
||||
Sep 22, 2006 R0.03 Added f_rename.
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast.
|
||||
Fixed f_mkdir creates incorrect directory on FAT32.
|
||||
|
||||
Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs)
|
||||
Changed some APIs for multiple drive system.
|
||||
Added f_mkfs. (FatFs)
|
||||
Added _USE_FAT32 option. (Tiny-FatFs)
|
||||
|
||||
Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs)
|
||||
Fixed an endian sensitive code in f_mkfs. (FatFs)
|
||||
Added a capability of extending the file size to f_lseek.
|
||||
Added minimization level 3.
|
||||
Fixed a problem that can collapse a sector when recreate an
|
||||
existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs)
|
||||
|
||||
May 05, 2007 R0.04b Added _USE_NTFLAG option.
|
||||
Added FSInfo support.
|
||||
Fixed some problems corresponds to FAT32. (Tiny-FatFs)
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (0 < ofs <= csize) collapses the file object.
|
||||
|
||||
Aug 25, 2007 R0.05 Changed arguments of f_read, f_write.
|
||||
Changed arguments of f_mkfs. (FatFs)
|
||||
Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs)
|
||||
Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs)
|
||||
|
||||
Feb 03, 2008 R0.05a Added f_truncate().
|
||||
Added f_utime().
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read() can be mistruncated.
|
||||
Fixed cached sector is not flushed when create and close without write.
|
||||
|
||||
Apr 01, 2008 R0.06 Added f_forward(). (Tiny-FatFs)
|
||||
Added string functions: fputc(), fputs(), fprintf() and fgets().
|
||||
Improved performance of f_lseek() on move to the same or following cluster.
|
||||
|
||||
Apr 01, 2009, R0.07 Merged Tiny-FatFs as a buffer configuration option.
|
||||
Added long file name support.
|
||||
Added multiple code page support.
|
||||
Added re-entrancy for multitask operation.
|
||||
Added auto cluster size selection to f_mkfs().
|
||||
Added rewind option to f_readdir().
|
||||
Changed result code of critical errors.
|
||||
Renamed string functions to avoid name collision.
|
||||
|
||||
Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg.
|
||||
Added multiple sector size support.
|
||||
|
||||
Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added relative path feature.
|
||||
Added f_chdir().
|
||||
Added f_chdrive().
|
||||
Added proper case conversion for extended characters.
|
||||
|
||||
Nov 03, 2009 R0.07e Separated out configuration options from ff.h to ffconf.h.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH.
|
||||
Fixed name matching error on the 13 char boundary.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
May 15, 2010, R0.08 Added a memory configuration option. (_USE_LFN)
|
||||
Added file lock feature. (_FS_SHARE)
|
||||
Added fast seek feature. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed fname member in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase feature. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write().
|
||||
f_lseek() reports required table size on creating CLMP.
|
||||
Extended format syntax of f_printf function.
|
||||
Ignores duplicated directory separators in given path names.
|
||||
|
||||
Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature.
|
||||
Added f_fdisk(). (_MULTI_PARTITION = 2)
|
||||
|
||||
Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16.
|
||||
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
|
||||
Jan 23,'13 R0.09b Added f_getlabel() and f_setlabel(). (_USE_LABEL == 1)
|
||||
|
||||
Oct 02,'13 R0.10 Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||
Added forced mount feature with changes of f_mount().
|
||||
Improved behavior of volume auto detection.
|
||||
Improved write throughput of f_puts() and f_printf().
|
||||
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
|
@ -1,539 +0,0 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Unicode - Local code bidirectional converter (C)ChaN, 2012 */
|
||||
/* (SBCS code pages) */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 437 U.S. (OEM)
|
||||
/ 720 Arabic (OEM)
|
||||
/ 1256 Arabic (Windows)
|
||||
/ 737 Greek (OEM)
|
||||
/ 1253 Greek (Windows)
|
||||
/ 1250 Central Europe (Windows)
|
||||
/ 775 Baltic (OEM)
|
||||
/ 1257 Baltic (Windows)
|
||||
/ 850 Multilingual Latin 1 (OEM)
|
||||
/ 852 Latin 2 (OEM)
|
||||
/ 1252 Latin 1 (Windows)
|
||||
/ 855 Cyrillic (OEM)
|
||||
/ 1251 Cyrillic (Windows)
|
||||
/ 866 Russian (OEM)
|
||||
/ 857 Turkish (OEM)
|
||||
/ 1254 Turkish (Windows)
|
||||
/ 858 Multilingual Latin 1 + Euro (OEM)
|
||||
/ 862 Hebrew (OEM)
|
||||
/ 1255 Hebrew (Windows)
|
||||
/ 874 Thai (OEM, Windows)
|
||||
/ 1258 Vietnam (OEM, Windows)
|
||||
*/
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
#if _CODE_PAGE == 437
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 720
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
|
||||
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
|
||||
0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
|
||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
|
||||
0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
|
||||
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 737
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
|
||||
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
|
||||
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
||||
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
|
||||
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
||||
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
|
||||
0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD,
|
||||
0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
|
||||
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 775
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
|
||||
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
|
||||
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
|
||||
0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
||||
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6,
|
||||
0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118,
|
||||
0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
|
||||
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
|
||||
0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
|
||||
0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
|
||||
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
|
||||
0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 850
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
|
||||
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 852
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
|
||||
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
||||
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
|
||||
0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E,
|
||||
0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A,
|
||||
0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
|
||||
0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
|
||||
0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
|
||||
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 855
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
|
||||
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
|
||||
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
||||
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
|
||||
0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
||||
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
|
||||
0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
|
||||
0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
|
||||
0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
|
||||
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
|
||||
0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
|
||||
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
|
||||
0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 857
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
|
||||
0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 858
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
|
||||
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 862
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
|
||||
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
|
||||
0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 866
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
|
||||
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
|
||||
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
|
||||
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 874
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
|
||||
0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
|
||||
0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
|
||||
0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
|
||||
0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
|
||||
0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
|
||||
0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
|
||||
0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
|
||||
0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
|
||||
0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
|
||||
0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
|
||||
0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1250
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
|
||||
0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
|
||||
0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
|
||||
0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
|
||||
0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
|
||||
0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
|
||||
0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
|
||||
0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
|
||||
0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
|
||||
0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
|
||||
0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1251
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */
|
||||
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
|
||||
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
|
||||
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
|
||||
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
|
||||
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
|
||||
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
|
||||
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
|
||||
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1252
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1253
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
|
||||
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
|
||||
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
|
||||
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
|
||||
0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
|
||||
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
|
||||
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
|
||||
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
|
||||
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1254
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1255
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
|
||||
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
|
||||
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
|
||||
0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
|
||||
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
|
||||
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1256
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
|
||||
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
|
||||
0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
|
||||
0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
|
||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
|
||||
0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643,
|
||||
0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
|
||||
0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
|
||||
0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2
|
||||
}
|
||||
|
||||
#elif _CODE_PAGE == 1257
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
|
||||
0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
|
||||
0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
|
||||
0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
|
||||
0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
|
||||
0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
|
||||
0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
|
||||
0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
|
||||
0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1258
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if _TBLDEF || _USE_LFN
|
||||
|
||||
|
||||
WCHAR ff_convert ( /* Converted character, Returns zero on error */
|
||||
WCHAR chr, /* Character code to be converted */
|
||||
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
|
||||
)
|
||||
{
|
||||
WCHAR c;
|
||||
|
||||
|
||||
if (chr < 0x80) { /* ASCII */
|
||||
c = chr;
|
||||
|
||||
} else {
|
||||
if (dir) { /* OEMCP to Unicode */
|
||||
c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80];
|
||||
|
||||
} else { /* Unicode to OEMCP */
|
||||
for (c = 0; c < 0x80; c++) {
|
||||
if (chr == Tbl[c]) break;
|
||||
}
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
WCHAR ff_wtoupper ( /* Upper converted character */
|
||||
WCHAR chr /* Input character */
|
||||
)
|
||||
{
|
||||
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 };
|
||||
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 };
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
|
||||
|
||||
return tbl_lower[i] ? tbl_upper[i] : chr;
|
||||
}
|
||||
#endif
|
@ -1,197 +0,0 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2013 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* If a working storage control module is available, it should be */
|
||||
/* attached to the FatFs via a glue function rather than modifying it. */
|
||||
/* This is an example of glue functions to attach various exsisting */
|
||||
/* storage control module to the FatFs module with a defined API. */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "ff.h" /* FatFs lower layer API */
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "misc.h"
|
||||
#include "storage.h"
|
||||
#include "sdcard.h"
|
||||
|
||||
PARTITION VolToPart[] = {
|
||||
{0, 1}, // Logical drive 0 ==> Physical drive 0, 1st partition
|
||||
{1, 0}, // Logical drive 1 ==> Physical drive 1 (auto detection)
|
||||
/*
|
||||
{0, 2}, // Logical drive 2 ==> Physical drive 0, 2nd partition
|
||||
{0, 3}, // Logical drive 3 ==> Physical drive 0, 3rd partition
|
||||
*/
|
||||
};
|
||||
|
||||
/* Definitions of physical drive number for each media */
|
||||
#define PD_FLASH (0)
|
||||
#define PD_SDCARD (1)
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Initialize a Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber (0..) */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case PD_FLASH:
|
||||
storage_init();
|
||||
return 0;
|
||||
|
||||
case PD_SDCARD:
|
||||
if (!sdcard_power_on()) {
|
||||
return STA_NODISK;
|
||||
}
|
||||
// TODO return STA_PROTECT if SD card is read only
|
||||
return 0;
|
||||
}
|
||||
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Disk Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber (0..) */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case PD_FLASH :
|
||||
// flash is ready
|
||||
return 0;
|
||||
|
||||
case PD_SDCARD:
|
||||
// TODO return STA_PROTECT if SD card is read only
|
||||
return 0;
|
||||
}
|
||||
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
DWORD sector, /* Sector address (LBA) */
|
||||
UINT count /* Number of sectors to read (1..128) */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case PD_FLASH:
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!storage_read_block(buff + i * FLASH_BLOCK_SIZE, sector + i)) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
}
|
||||
return RES_OK;
|
||||
|
||||
case PD_SDCARD:
|
||||
// TODO have a multi-block read function
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!sdcard_read_block(buff + i * SDCARD_BLOCK_SIZE, sector + i)) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
}
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_WRITE
|
||||
DRESULT disk_write (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Sector address (LBA) */
|
||||
UINT count /* Number of sectors to write (1..128) */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case PD_FLASH:
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!storage_write_block(buff + i * FLASH_BLOCK_SIZE, sector + i)) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
}
|
||||
return RES_OK;
|
||||
|
||||
case PD_SDCARD:
|
||||
// TODO have a multi-block write function
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!sdcard_write_block(buff + i * SDCARD_BLOCK_SIZE, sector + i)) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
}
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
return RES_PARERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_IOCTL
|
||||
DRESULT disk_ioctl (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case PD_FLASH:
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC:
|
||||
storage_flush();
|
||||
return RES_OK;
|
||||
|
||||
case GET_BLOCK_SIZE:
|
||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the small (512) block size
|
||||
return RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case PD_SDCARD:
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC:
|
||||
return RES_OK;
|
||||
|
||||
case GET_BLOCK_SIZE:
|
||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the small (512) block size
|
||||
return RES_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return RES_PARERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
DWORD get_fattime (
|
||||
void
|
||||
)
|
||||
{
|
||||
// TODO replace with call to RTC
|
||||
int year = 2013;
|
||||
int month = 10;
|
||||
int day = 12;
|
||||
int hour = 21;
|
||||
int minute = 42;
|
||||
int second = 13;
|
||||
return ((year - 1980) << 25) | ((month) << 21) | ((day) << 16) | ((hour) << 11) | ((minute) << 5) | (second / 2);
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*-----------------------------------------------------------------------
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2013
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define _USE_WRITE 1 /* 1: Enable disk_write function */
|
||||
#define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE*buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
DWORD get_fattime (void);
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */
|
||||
#define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */
|
||||
|
||||
/* Generic command (not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
|
||||
/* MMC card type flags (MMC_GET_TYPE) */
|
||||
#define CT_MMC 0x01 /* MMC ver 3 */
|
||||
#define CT_SD1 0x02 /* SD ver 1 */
|
||||
#define CT_SD2 0x04 /* SD ver 2 */
|
||||
#define CT_SDC (CT_SD1|CT_SD2) /* SD */
|
||||
#define CT_BLOCK 0x08 /* Block addressing */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
4524
stm/fatfs/ff.c
4524
stm/fatfs/ff.c
File diff suppressed because it is too large
Load Diff
342
stm/fatfs/ff.h
342
stm/fatfs/ff.h
@ -1,342 +0,0 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.10 (C)ChaN, 2013
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is a generic FAT file system module for small embedded systems.
|
||||
/ This is a free software that opened for education, research and commercial
|
||||
/ developments under license policy of following terms.
|
||||
/
|
||||
/ Copyright (C) 2013, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _FATFS
|
||||
#define _FATFS 80960 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if _FATFS != _FFCONF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
|
||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */
|
||||
#define LD2PT(vol) 0 /* Find first valid partition or in SFD */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#if _LFN_UNICODE /* Unicode string */
|
||||
#if !_USE_LFN
|
||||
#error _LFN_UNICODE must be 0 in non-LFN cfg.
|
||||
#endif
|
||||
#ifndef _INC_TCHAR
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#endif
|
||||
|
||||
#else /* ANSI/OEM string */
|
||||
#ifndef _INC_TCHAR
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File system object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
|
||||
BYTE drv; /* Physical drive number */
|
||||
BYTE csize; /* Sectors per cluster (1,2,4...128) */
|
||||
BYTE n_fats; /* Number of FAT copies (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
#if _MAX_SS != 512
|
||||
WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
#endif
|
||||
#if _FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */
|
||||
DWORD fsize; /* Sectors per FAT */
|
||||
DWORD volbase; /* Volume start sector */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the related file system object (**do not change order**) */
|
||||
WORD id; /* Owner file system mount ID (**do not change order**) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
DWORD fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD sclust; /* File data start cluster (0:no data cluster, always 0 when fsize is 0) */
|
||||
DWORD clust; /* Current cluster of fpter */
|
||||
DWORD dsect; /* Current data sector of fpter */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector containing the directory entry */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the window */
|
||||
#endif
|
||||
#if _USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (Nulled on file open) */
|
||||
#endif
|
||||
#if _FS_LOCK
|
||||
UINT lockid; /* File lock ID (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS]; /* File data read/write buffer */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object (**do not change order**) */
|
||||
WORD id; /* Owner file system mount ID (**do not change order**) */
|
||||
WORD index; /* Current read/write index number */
|
||||
DWORD sclust; /* Table start cluster (0:Root dir) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||
#if _FS_LOCK
|
||||
UINT lockid; /* File lock ID (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
#if _USE_LFN
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File status structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
DWORD fsize; /* File size */
|
||||
WORD fdate; /* Last modified date */
|
||||
WORD ftime; /* Last modified time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
TCHAR fname[13]; /* Short file name (8.3 format) */
|
||||
#if _USE_LFN
|
||||
TCHAR* lfname; /* Pointer to the LFN buffer */
|
||||
UINT lfsize; /* Size of LFN buffer in TCHAR */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from a file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to a file */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_lseek (FIL* fp, DWORD ofs); /* Move file pointer of a file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of a writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE value, BYTE mask); /* Change attribute of the file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* sn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE sfd, UINT au); /* Create a file system on the volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD szt[], void* work); /* Divide a physical drive into some partitions */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->fsize)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !_FS_READONLY
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* Unicode support functions */
|
||||
#if _USE_LFN /* Unicode - OEM code conversion */
|
||||
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
|
||||
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
|
||||
#if _USE_LFN == 3 /* Memory functions */
|
||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if _FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access control and file status flags (FIL.flag) */
|
||||
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
|
||||
#if !_FS_READONLY
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
#endif
|
||||
|
||||
|
||||
/* FAT sub type (FATFS.fs_type) */
|
||||
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
|
||||
|
||||
/* File attribute bits for directory entry */
|
||||
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||
|
||||
|
||||
/* Fast seek feature */
|
||||
#define CREATE_LINKMAP 0xFFFFFFFF
|
||||
|
||||
|
||||
|
||||
/*--------------------------------*/
|
||||
/* Multi-byte word access macros */
|
||||
|
||||
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#else /* Use byte-by-byte access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FATFS */
|
@ -1,212 +0,0 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.10 (C)ChaN, 2013
|
||||
/----------------------------------------------------------------------------/
|
||||
/
|
||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||
/ the configuration options.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef _FFCONF
|
||||
#define _FFCONF 80960 /* Revision ID */
|
||||
|
||||
#include "mpconfigport.h"
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Functions and Buffer Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_TINY 1 /* 0:Normal or 1:Tiny */
|
||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||
/ object instead of the sector buffer in the individual file object for file
|
||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||
|
||||
|
||||
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
|
||||
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
||||
/ writing functions, f_write(), f_sync(), f_unlink(), f_mkdir(), f_chmod(),
|
||||
/ f_rename(), f_truncate() and useless f_getfree(). */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0 /* 0 to 3 */
|
||||
/* The _FS_MINIMIZE option defines minimization level to remove API functions.
|
||||
/
|
||||
/ 0: All basic functions are enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(),
|
||||
/ f_truncate() and f_rename() function are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 0 /* 0:Disable or 1-2:Enable */
|
||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||
|
||||
|
||||
#define _USE_MKFS 1 /* 0:Disable or 1:Enable */
|
||||
/* To enable f_mkfs() function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
|
||||
|
||||
|
||||
#define _USE_LABEL 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable volume label functions, set _USE_LAVEL to 1 */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable f_forward() function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _CODE_PAGE (MICROPY_LFN_CODE_PAGE)
|
||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII (Valid for only non-LFN cfg.)
|
||||
*/
|
||||
|
||||
#define _USE_LFN (MICROPY_ENABLE_LFN) /* 0 to 3 */
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
||||
/* The _USE_LFN option switches the LFN feature.
|
||||
/
|
||||
/ 0: Disable LFN feature. _MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable LFN feature, Unicode handling functions ff_convert() and ff_wtoupper()
|
||||
/ function must be added to the project.
|
||||
/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When use stack for the
|
||||
/ working buffer, take care on stack overflow. When use heap memory for the working
|
||||
/ buffer, memory management functions, ff_memalloc() and ff_memfree(), must be added
|
||||
/ to the project. */
|
||||
|
||||
|
||||
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
|
||||
/* To switch the character encoding on the FatFs API to Unicode, enable LFN feature
|
||||
/ and set _LFN_UNICODE to 1. */
|
||||
|
||||
|
||||
#define _STRF_ENCODE 3 /* 0:ANSI/OEM, 1:UTF-16LE, 2:UTF-16BE, 3:UTF-8 */
|
||||
/* When Unicode API is enabled, character encoding on the all FatFs API is switched
|
||||
/ to Unicode. This option selects the character encoding on the file to be read/written
|
||||
/ via string functions, f_gets(), f_putc(), f_puts and f_printf().
|
||||
/ This option has no effect when _LFN_UNICODE is 0. */
|
||||
|
||||
|
||||
#define _FS_RPATH 0 /* 0 to 2 */
|
||||
/* The _FS_RPATH option configures relative path feature.
|
||||
/
|
||||
/ 0: Disable relative path feature and remove related functions.
|
||||
/ 1: Enable relative path. f_chdrive() and f_chdir() function are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
/
|
||||
/ Note that output of the f_readdir() fnction is affected by this option. */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 2
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 1 /* 0:Single partition, 1:Enable multiple partition */
|
||||
/* When set to 0, each volume is bound to the same physical drive number and
|
||||
/ it can mount only first primaly partition. When it is set to 1, each volume
|
||||
/ is tied to the partitions listed in VolToPart[]. */
|
||||
|
||||
|
||||
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
|
||||
/* Maximum sector size to be handled.
|
||||
/ Always set 512 for memory card and hard disk but a larger value may be
|
||||
/ required for on-board flash memory, floppy disk and optical disk.
|
||||
/ When _MAX_SS is larger than 512, it configures FatFs to variable sector size
|
||||
/ and GET_SECTOR_SIZE command must be implemented to the disk_ioctl() function. */
|
||||
|
||||
|
||||
#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable sector erase feature, set _USE_ERASE to 1. Also CTRL_ERASE_SECTOR command
|
||||
/ should be added to the disk_ioctl() function. */
|
||||
|
||||
|
||||
#define _FS_NOFSINFO 0 /* 0 or 1 */
|
||||
/* If you need to know the correct free space on the FAT32 volume, set this
|
||||
/ option to 1 and f_getfree() function at first time after volume mount will
|
||||
/ force a full FAT scan.
|
||||
/
|
||||
/ 0: Load all informations in the FSINFO if available.
|
||||
/ 1: Do not trust free cluster count in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _WORD_ACCESS 0 /* 0 or 1 */
|
||||
/* The _WORD_ACCESS option is an only platform dependent option. It defines
|
||||
/ which access method is used to the word data on the FAT volume.
|
||||
/
|
||||
/ 0: Byte-by-byte access. Always compatible with all platforms.
|
||||
/ 1: Word access. Do not choose this unless under both the following conditions.
|
||||
/
|
||||
/ * Byte order on the memory is little-endian.
|
||||
/ * Address miss-aligned word access is always allowed for all instructions.
|
||||
/
|
||||
/ If it is the case, _WORD_ACCESS can also be set to 1 to improve performance
|
||||
/ and reduce code size.
|
||||
*/
|
||||
|
||||
|
||||
/* A header file that defines sync object types on the O/S, such as
|
||||
/ windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */
|
||||
|
||||
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
|
||||
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||
|
||||
/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs module.
|
||||
/
|
||||
/ 0: Disable re-entrancy. _SYNC_t and _FS_TIMEOUT have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function must be added to the project. */
|
||||
|
||||
|
||||
#define _FS_LOCK 0 /* 0:Disable or >=1:Enable */
|
||||
/* To enable file lock control feature, set _FS_LOCK to 1 or greater.
|
||||
The value defines how many files can be opened simultaneously. */
|
||||
|
||||
|
||||
#endif /* _FFCONFIG */
|
@ -1,33 +0,0 @@
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef _FF_INTEGER
|
||||
#define _FF_INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* This type MUST be 8 bit */
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types MUST be 16 bit */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types MUST be 16 bit or 32 bit */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* These types MUST be 32 bit */
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
97
stm/file.c
97
stm/file.c
@ -1,97 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stm32f4xx.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "file.h"
|
||||
#include "ff.h"
|
||||
|
||||
typedef struct _pyb_file_obj_t {
|
||||
mp_obj_base_t base;
|
||||
FIL fp;
|
||||
} pyb_file_obj_t;
|
||||
|
||||
void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
printf("<file %p>", self_in);
|
||||
}
|
||||
|
||||
mp_obj_t file_obj_read(mp_obj_t self_in, mp_obj_t arg) {
|
||||
pyb_file_obj_t *self = self_in;
|
||||
int n = mp_obj_get_int(arg);
|
||||
byte *buf = m_new(byte, n);
|
||||
UINT n_out;
|
||||
f_read(&self->fp, buf, n, &n_out);
|
||||
return mp_obj_new_str(buf, n_out, false);
|
||||
}
|
||||
|
||||
mp_obj_t file_obj_write(mp_obj_t self_in, mp_obj_t arg) {
|
||||
pyb_file_obj_t *self = self_in;
|
||||
uint l;
|
||||
const char *s = mp_obj_str_get_data(arg, &l);
|
||||
UINT n_out;
|
||||
FRESULT res = f_write(&self->fp, s, l, &n_out);
|
||||
if (res != FR_OK) {
|
||||
printf("File error: could not write to file; error code %d\n", res);
|
||||
} else if (n_out != l) {
|
||||
printf("File error: could not write all data to file; wrote %d / %d bytes\n", n_out, l);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t file_obj_close(mp_obj_t self_in) {
|
||||
pyb_file_obj_t *self = self_in;
|
||||
f_close(&self->fp);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(file_obj_read_obj, file_obj_read);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(file_obj_write_obj, file_obj_write);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(file_obj_close_obj, file_obj_close);
|
||||
|
||||
// TODO gc hook to close the file if not already closed
|
||||
|
||||
STATIC const mp_map_elem_t file_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&file_obj_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&file_obj_write_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&file_obj_close_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&file_obj_close_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(file_locals_dict, file_locals_dict_table);
|
||||
|
||||
static const mp_obj_type_t file_obj_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_File,
|
||||
.print = file_obj_print,
|
||||
.locals_dict = (mp_obj_t)&file_locals_dict,
|
||||
};
|
||||
|
||||
mp_obj_t pyb_io_open(mp_obj_t o_filename, mp_obj_t o_mode) {
|
||||
const char *filename = mp_obj_str_get_str(o_filename);
|
||||
const char *mode = mp_obj_str_get_str(o_mode);
|
||||
pyb_file_obj_t *self = m_new_obj_with_finaliser(pyb_file_obj_t);
|
||||
self->base.type = &file_obj_type;
|
||||
if (mode[0] == 'r') {
|
||||
// open for reading
|
||||
FRESULT res = f_open(&self->fp, filename, FA_READ);
|
||||
if (res != FR_OK) {
|
||||
printf("FileNotFoundError: [Errno 2] No such file or directory: '%s'\n", filename);
|
||||
return mp_const_none;
|
||||
}
|
||||
} else if (mode[0] == 'w') {
|
||||
// open for writing, truncate the file first
|
||||
FRESULT res = f_open(&self->fp, filename, FA_WRITE | FA_CREATE_ALWAYS);
|
||||
if (res != FR_OK) {
|
||||
printf("?FileError: could not create file: '%s'\n", filename);
|
||||
return mp_const_none;
|
||||
}
|
||||
} else {
|
||||
printf("ValueError: invalid mode: '%s'\n", mode);
|
||||
return mp_const_none;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_open_obj, pyb_io_open);
|
@ -1 +0,0 @@
|
||||
mp_obj_t pyb_io_open(mp_obj_t o_filename, mp_obj_t o_mode);
|
121
stm/flash.c
121
stm/flash.c
@ -1,121 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_flash.h>
|
||||
#include "flash.h"
|
||||
|
||||
/* Base address of the Flash sectors */
|
||||
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */
|
||||
|
||||
static const uint32_t flash_info_table[26] = {
|
||||
ADDR_FLASH_SECTOR_0, FLASH_Sector_0,
|
||||
ADDR_FLASH_SECTOR_1, FLASH_Sector_1,
|
||||
ADDR_FLASH_SECTOR_2, FLASH_Sector_2,
|
||||
ADDR_FLASH_SECTOR_3, FLASH_Sector_3,
|
||||
ADDR_FLASH_SECTOR_4, FLASH_Sector_4,
|
||||
ADDR_FLASH_SECTOR_5, FLASH_Sector_5,
|
||||
ADDR_FLASH_SECTOR_6, FLASH_Sector_6,
|
||||
ADDR_FLASH_SECTOR_7, FLASH_Sector_7,
|
||||
ADDR_FLASH_SECTOR_8, FLASH_Sector_8,
|
||||
ADDR_FLASH_SECTOR_9, FLASH_Sector_9,
|
||||
ADDR_FLASH_SECTOR_10, FLASH_Sector_10,
|
||||
ADDR_FLASH_SECTOR_11, FLASH_Sector_11,
|
||||
ADDR_FLASH_SECTOR_11 + 0x20000, 0,
|
||||
};
|
||||
|
||||
uint32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size) {
|
||||
if (addr >= flash_info_table[0]) {
|
||||
for (int i = 0; i < 24; i += 2) {
|
||||
if (addr < flash_info_table[i + 2]) {
|
||||
if (start_addr != NULL) {
|
||||
*start_addr = flash_info_table[i];
|
||||
}
|
||||
if (size != NULL) {
|
||||
*size = flash_info_table[i + 2] - flash_info_table[i];
|
||||
}
|
||||
return flash_info_table[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* @brief Gets the sector of a given address
|
||||
* @param None
|
||||
* @retval The sector of a given address
|
||||
*/
|
||||
uint32_t flash_get_sector(uint32_t addr) {
|
||||
if ((addr < ADDR_FLASH_SECTOR_1) && (addr >= ADDR_FLASH_SECTOR_0)) {
|
||||
return FLASH_Sector_0;
|
||||
} else if ((addr < ADDR_FLASH_SECTOR_2) && (addr >= ADDR_FLASH_SECTOR_1)) {
|
||||
return FLASH_Sector_1;
|
||||
} else if ((addr < ADDR_FLASH_SECTOR_3) && (addr >= ADDR_FLASH_SECTOR_2)) {
|
||||
return FLASH_Sector_2;
|
||||
} else if ((addr < ADDR_FLASH_SECTOR_4) && (addr >= ADDR_FLASH_SECTOR_3)) {
|
||||
return FLASH_Sector_3;
|
||||
} else if ((addr < ADDR_FLASH_SECTOR_5) && (addr >= ADDR_FLASH_SECTOR_4)) {
|
||||
return FLASH_Sector_4;
|
||||
} else if ((addr < ADDR_FLASH_SECTOR_6) && (addr >= ADDR_FLASH_SECTOR_5)) {
|
||||
return FLASH_Sector_5;
|
||||
} else if ((addr < ADDR_FLASH_SECTOR_7) && (addr >= ADDR_FLASH_SECTOR_6)) {
|
||||
return FLASH_Sector_6;
|
||||
} else if ((addr < ADDR_FLASH_SECTOR_8) && (addr >= ADDR_FLASH_SECTOR_7)) {
|
||||
return FLASH_Sector_7;
|
||||
} else if ((addr < ADDR_FLASH_SECTOR_9) && (addr >= ADDR_FLASH_SECTOR_8)) {
|
||||
return FLASH_Sector_8;
|
||||
} else if ((addr < ADDR_FLASH_SECTOR_10) && (addr >= ADDR_FLASH_SECTOR_9)) {
|
||||
return FLASH_Sector_9;
|
||||
} else if ((addr < ADDR_FLASH_SECTOR_11) && (addr >= ADDR_FLASH_SECTOR_10)) {
|
||||
return FLASH_Sector_10;
|
||||
} else {
|
||||
return FLASH_Sector_11;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
|
||||
// unlock
|
||||
FLASH_Unlock();
|
||||
|
||||
// Clear pending flags (if any)
|
||||
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
|
||||
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
|
||||
|
||||
// Device voltage range supposed to be [2.7V to 3.6V], the operation will be done by word
|
||||
if (FLASH_EraseSector(flash_get_sector_info(flash_dest, NULL, NULL), VoltageRange_3) != FLASH_COMPLETE) {
|
||||
/* Error occurred while sector erase.
|
||||
User can add here some code to deal with this error */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Program the user Flash area word by word ********************************/
|
||||
|
||||
for (int i = 0; i < num_word32; i++) {
|
||||
if (FLASH_ProgramWord(flash_dest, *src) == FLASH_COMPLETE)
|
||||
{
|
||||
flash_dest += 4;
|
||||
src += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error occurred while writing data in Flash memory.
|
||||
User can add here some code to deal with this error */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// lock
|
||||
FLASH_Lock();
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
uint32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size);
|
||||
void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32);
|
@ -1,98 +0,0 @@
|
||||
const uint8_t font_petme128_8x8[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 32=
|
||||
0x00,0x00,0x00,0x4f,0x4f,0x00,0x00,0x00, // 33=!
|
||||
0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, // 34="
|
||||
0x14,0x7f,0x7f,0x14,0x14,0x7f,0x7f,0x14, // 35=#
|
||||
0x00,0x24,0x2e,0x6b,0x6b,0x3a,0x12,0x00, // 36=$
|
||||
0x00,0x63,0x33,0x18,0x0c,0x66,0x63,0x00, // 37=%
|
||||
0x00,0x32,0x7f,0x4d,0x4d,0x77,0x72,0x50, // 38=&
|
||||
0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00, // 39='
|
||||
0x00,0x00,0x1c,0x3e,0x63,0x41,0x00,0x00, // 40=(
|
||||
0x00,0x00,0x41,0x63,0x3e,0x1c,0x00,0x00, // 41=)
|
||||
0x08,0x2a,0x3e,0x1c,0x1c,0x3e,0x2a,0x08, // 42=*
|
||||
0x00,0x08,0x08,0x3e,0x3e,0x08,0x08,0x00, // 43=+
|
||||
0x00,0x00,0x80,0xe0,0x60,0x00,0x00,0x00, // 44=,
|
||||
0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, // 45=-
|
||||
0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, // 46=.
|
||||
0x00,0x40,0x60,0x30,0x18,0x0c,0x06,0x02, // 47=/
|
||||
0x00,0x3e,0x7f,0x49,0x45,0x7f,0x3e,0x00, // 48=0
|
||||
0x00,0x40,0x44,0x7f,0x7f,0x40,0x40,0x00, // 49=1
|
||||
0x00,0x62,0x73,0x51,0x49,0x4f,0x46,0x00, // 50=2
|
||||
0x00,0x22,0x63,0x49,0x49,0x7f,0x36,0x00, // 51=3
|
||||
0x00,0x18,0x18,0x14,0x16,0x7f,0x7f,0x10, // 52=4
|
||||
0x00,0x27,0x67,0x45,0x45,0x7d,0x39,0x00, // 53=5
|
||||
0x00,0x3e,0x7f,0x49,0x49,0x7b,0x32,0x00, // 54=6
|
||||
0x00,0x03,0x03,0x79,0x7d,0x07,0x03,0x00, // 55=7
|
||||
0x00,0x36,0x7f,0x49,0x49,0x7f,0x36,0x00, // 56=8
|
||||
0x00,0x26,0x6f,0x49,0x49,0x7f,0x3e,0x00, // 57=9
|
||||
0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x00, // 58=:
|
||||
0x00,0x00,0x80,0xe4,0x64,0x00,0x00,0x00, // 59=;
|
||||
0x00,0x08,0x1c,0x36,0x63,0x41,0x41,0x00, // 60=<
|
||||
0x00,0x14,0x14,0x14,0x14,0x14,0x14,0x00, // 61==
|
||||
0x00,0x41,0x41,0x63,0x36,0x1c,0x08,0x00, // 62=>
|
||||
0x00,0x02,0x03,0x51,0x59,0x0f,0x06,0x00, // 63=?
|
||||
0x00,0x3e,0x7f,0x41,0x4d,0x4f,0x2e,0x00, // 64=@
|
||||
0x00,0x7c,0x7e,0x0b,0x0b,0x7e,0x7c,0x00, // 65=A
|
||||
0x00,0x7f,0x7f,0x49,0x49,0x7f,0x36,0x00, // 66=B
|
||||
0x00,0x3e,0x7f,0x41,0x41,0x63,0x22,0x00, // 67=C
|
||||
0x00,0x7f,0x7f,0x41,0x63,0x3e,0x1c,0x00, // 68=D
|
||||
0x00,0x7f,0x7f,0x49,0x49,0x41,0x41,0x00, // 69=E
|
||||
0x00,0x7f,0x7f,0x09,0x09,0x01,0x01,0x00, // 70=F
|
||||
0x00,0x3e,0x7f,0x41,0x49,0x7b,0x3a,0x00, // 71=G
|
||||
0x00,0x7f,0x7f,0x08,0x08,0x7f,0x7f,0x00, // 72=H
|
||||
0x00,0x00,0x41,0x7f,0x7f,0x41,0x00,0x00, // 73=I
|
||||
0x00,0x20,0x60,0x41,0x7f,0x3f,0x01,0x00, // 74=J
|
||||
0x00,0x7f,0x7f,0x1c,0x36,0x63,0x41,0x00, // 75=K
|
||||
0x00,0x7f,0x7f,0x40,0x40,0x40,0x40,0x00, // 76=L
|
||||
0x00,0x7f,0x7f,0x06,0x0c,0x06,0x7f,0x7f, // 77=M
|
||||
0x00,0x7f,0x7f,0x0e,0x1c,0x7f,0x7f,0x00, // 78=N
|
||||
0x00,0x3e,0x7f,0x41,0x41,0x7f,0x3e,0x00, // 79=O
|
||||
0x00,0x7f,0x7f,0x09,0x09,0x0f,0x06,0x00, // 80=P
|
||||
0x00,0x1e,0x3f,0x21,0x61,0x7f,0x5e,0x00, // 81=Q
|
||||
0x00,0x7f,0x7f,0x19,0x39,0x6f,0x46,0x00, // 82=R
|
||||
0x00,0x26,0x6f,0x49,0x49,0x7b,0x32,0x00, // 83=S
|
||||
0x00,0x01,0x01,0x7f,0x7f,0x01,0x01,0x00, // 84=T
|
||||
0x00,0x3f,0x7f,0x40,0x40,0x7f,0x3f,0x00, // 85=U
|
||||
0x00,0x1f,0x3f,0x60,0x60,0x3f,0x1f,0x00, // 86=V
|
||||
0x00,0x7f,0x7f,0x30,0x18,0x30,0x7f,0x7f, // 87=W
|
||||
0x00,0x63,0x77,0x1c,0x1c,0x77,0x63,0x00, // 88=X
|
||||
0x00,0x07,0x0f,0x78,0x78,0x0f,0x07,0x00, // 89=Y
|
||||
0x00,0x61,0x71,0x59,0x4d,0x47,0x43,0x00, // 90=Z
|
||||
0x00,0x00,0x7f,0x7f,0x41,0x41,0x00,0x00, // 91=[
|
||||
0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0x40, // 92='\'
|
||||
0x00,0x00,0x41,0x41,0x7f,0x7f,0x00,0x00, // 93=]
|
||||
0x00,0x08,0x0c,0x06,0x06,0x0c,0x08,0x00, // 94=^
|
||||
0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, // 95=_
|
||||
0x00,0x00,0x01,0x03,0x06,0x04,0x00,0x00, // 96=`
|
||||
0x00,0x20,0x74,0x54,0x54,0x7c,0x78,0x00, // 97=a
|
||||
0x00,0x7f,0x7f,0x44,0x44,0x7c,0x38,0x00, // 98=b
|
||||
0x00,0x38,0x7c,0x44,0x44,0x6c,0x28,0x00, // 99=c
|
||||
0x00,0x38,0x7c,0x44,0x44,0x7f,0x7f,0x00, // 100=d
|
||||
0x00,0x38,0x7c,0x54,0x54,0x5c,0x58,0x00, // 101=e
|
||||
0x00,0x08,0x7e,0x7f,0x09,0x03,0x02,0x00, // 102=f
|
||||
0x00,0x98,0xbc,0xa4,0xa4,0xfc,0x7c,0x00, // 103=g
|
||||
0x00,0x7f,0x7f,0x04,0x04,0x7c,0x78,0x00, // 104=h
|
||||
0x00,0x00,0x00,0x7d,0x7d,0x00,0x00,0x00, // 105=i
|
||||
0x00,0x40,0xc0,0x80,0x80,0xfd,0x7d,0x00, // 106=j
|
||||
0x00,0x7f,0x7f,0x30,0x38,0x6c,0x44,0x00, // 107=k
|
||||
0x00,0x00,0x41,0x7f,0x7f,0x40,0x00,0x00, // 108=l
|
||||
0x00,0x7c,0x7c,0x18,0x30,0x18,0x7c,0x7c, // 109=m
|
||||
0x00,0x7c,0x7c,0x04,0x04,0x7c,0x78,0x00, // 110=n
|
||||
0x00,0x38,0x7c,0x44,0x44,0x7c,0x38,0x00, // 111=o
|
||||
0x00,0xfc,0xfc,0x24,0x24,0x3c,0x18,0x00, // 112=p
|
||||
0x00,0x18,0x3c,0x24,0x24,0xfc,0xfc,0x00, // 113=q
|
||||
0x00,0x7c,0x7c,0x04,0x04,0x0c,0x08,0x00, // 114=r
|
||||
0x00,0x48,0x5c,0x54,0x54,0x74,0x20,0x00, // 115=s
|
||||
0x04,0x04,0x3f,0x7f,0x44,0x64,0x20,0x00, // 116=t
|
||||
0x00,0x3c,0x7c,0x40,0x40,0x7c,0x3c,0x00, // 117=u
|
||||
0x00,0x1c,0x3c,0x60,0x60,0x3c,0x1c,0x00, // 118=v
|
||||
0x00,0x1c,0x7c,0x30,0x18,0x30,0x7c,0x1c, // 119=w
|
||||
0x00,0x44,0x6c,0x38,0x38,0x6c,0x44,0x00, // 120=x
|
||||
0x00,0x9c,0xbc,0xa0,0xa0,0xfc,0x7c,0x00, // 121=y
|
||||
0x00,0x44,0x64,0x74,0x5c,0x4c,0x44,0x00, // 122=z
|
||||
0x00,0x08,0x08,0x3e,0x77,0x41,0x41,0x00, // 123={
|
||||
0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00, // 124=|
|
||||
0x00,0x41,0x41,0x77,0x3e,0x08,0x08,0x00, // 125=}
|
||||
0x00,0x02,0x03,0x01,0x03,0x02,0x03,0x01, // 126=~
|
||||
0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, // 127
|
||||
};
|
@ -1,55 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "gc.h"
|
||||
#include "gccollect.h"
|
||||
#include "systick.h"
|
||||
|
||||
machine_uint_t gc_helper_get_regs_and_sp(machine_uint_t *regs);
|
||||
|
||||
// obsolete
|
||||
// void gc_helper_get_regs_and_clean_stack(machine_uint_t *regs, machine_uint_t heap_end);
|
||||
|
||||
void gc_collect(void) {
|
||||
// get current time, in case we want to time the GC
|
||||
uint32_t start = sys_tick_counter;
|
||||
|
||||
// start the GC
|
||||
gc_collect_start();
|
||||
|
||||
// scan everything in RAM before the heap
|
||||
// this includes the data and bss segments
|
||||
// TODO possibly don't need to scan data, since all pointers should start out NULL and be in bss
|
||||
gc_collect_root((void**)&_ram_start, ((uint32_t)&_bss_end - (uint32_t)&_ram_start) / sizeof(uint32_t));
|
||||
|
||||
// get the registers and the sp
|
||||
machine_uint_t regs[10];
|
||||
machine_uint_t sp = gc_helper_get_regs_and_sp(regs);
|
||||
|
||||
// trace the stack, including the registers (since they live on the stack in this function)
|
||||
gc_collect_root((void**)sp, ((uint32_t)&_ram_end - sp) / sizeof(uint32_t));
|
||||
|
||||
// end the GC
|
||||
gc_collect_end();
|
||||
|
||||
if (0) {
|
||||
// print GC info
|
||||
uint32_t ticks = sys_tick_counter - start; // TODO implement a function that does this properly
|
||||
gc_info_t info;
|
||||
gc_info(&info);
|
||||
printf("GC@%lu %lums\n", start, ticks);
|
||||
printf(" %lu total\n", info.total);
|
||||
printf(" %lu : %lu\n", info.used, info.free);
|
||||
printf(" 1=%lu 2=%lu m=%lu\n", info.num_1block, info.num_2block, info.max_block);
|
||||
}
|
||||
}
|
||||
|
||||
static mp_obj_t pyb_gc(void) {
|
||||
gc_collect();
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_gc_obj, pyb_gc);
|
@ -1,17 +0,0 @@
|
||||
// variables defining memory layout
|
||||
// (these probably belong somewhere else...)
|
||||
extern uint32_t _text_end;
|
||||
extern uint32_t _data_start_init;
|
||||
extern uint32_t _ram_start;
|
||||
extern uint32_t _data_start;
|
||||
extern uint32_t _data_end;
|
||||
extern uint32_t _bss_start;
|
||||
extern uint32_t _bss_end;
|
||||
extern uint32_t _heap_start;
|
||||
extern uint32_t _heap_end;
|
||||
extern uint32_t _stack_end;
|
||||
extern uint32_t _ram_end;
|
||||
|
||||
void gc_collect(void);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_gc_obj);
|
@ -1,62 +0,0 @@
|
||||
.syntax unified
|
||||
.cpu cortex-m4
|
||||
.thumb
|
||||
.text
|
||||
.align 2
|
||||
|
||||
@ uint gc_helper_get_regs_and_sp(r0=uint regs[10])
|
||||
.global gc_helper_get_regs_and_sp
|
||||
.thumb
|
||||
.thumb_func
|
||||
.type gc_helper_get_regs_and_sp, %function
|
||||
gc_helper_get_regs_and_sp:
|
||||
@ store registers into given array
|
||||
str r4, [r0], #4
|
||||
str r5, [r0], #4
|
||||
str r6, [r0], #4
|
||||
str r7, [r0], #4
|
||||
str r8, [r0], #4
|
||||
str r9, [r0], #4
|
||||
str r10, [r0], #4
|
||||
str r11, [r0], #4
|
||||
str r12, [r0], #4
|
||||
str r13, [r0], #4
|
||||
|
||||
@ return the sp
|
||||
mov r0, sp
|
||||
bx lr
|
||||
|
||||
|
||||
@ this next function is now obsolete
|
||||
|
||||
.size gc_helper_get_regs_and_clean_stack, .-gc_helper_get_regs_and_clean_stack
|
||||
@ void gc_helper_get_regs_and_clean_stack(r0=uint regs[10], r1=heap_end)
|
||||
.global gc_helper_get_regs_and_clean_stack
|
||||
.thumb
|
||||
.thumb_func
|
||||
.type gc_helper_get_regs_and_clean_stack, %function
|
||||
gc_helper_get_regs_and_clean_stack:
|
||||
@ store registers into given array
|
||||
str r4, [r0], #4
|
||||
str r5, [r0], #4
|
||||
str r6, [r0], #4
|
||||
str r7, [r0], #4
|
||||
str r8, [r0], #4
|
||||
str r9, [r0], #4
|
||||
str r10, [r0], #4
|
||||
str r11, [r0], #4
|
||||
str r12, [r0], #4
|
||||
str r13, [r0], #4
|
||||
|
||||
@ clean the stack from given pointer up to current sp
|
||||
movs r0, #0
|
||||
mov r2, sp
|
||||
b.n .entry
|
||||
.loop:
|
||||
str r0, [r1], #4
|
||||
.entry:
|
||||
cmp r1, r2
|
||||
bcc.n .loop
|
||||
bx lr
|
||||
|
||||
.size gc_helper_get_regs_and_clean_stack, .-gc_helper_get_regs_and_clean_stack
|
94
stm/gpio.c
94
stm/gpio.c
@ -1,94 +0,0 @@
|
||||
// This is a woefully inadequate set of bindings for GPIO control, and
|
||||
// needs to be replaced with something much better.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_rcc.h>
|
||||
#include <stm32f4xx_syscfg.h>
|
||||
#include <stm32f4xx_gpio.h>
|
||||
#include <stm32f4xx_exti.h>
|
||||
#include <stm32f4xx_tim.h>
|
||||
#include <stm32f4xx_pwr.h>
|
||||
#include <stm32f4xx_rtc.h>
|
||||
#include <stm32f4xx_usart.h>
|
||||
#include <stm32f4xx_rng.h>
|
||||
#include <usbd_storage_msd.h>
|
||||
#include <stm_misc.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "misc.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "compile.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
#include "systick.h"
|
||||
#include "gpio.h"
|
||||
#include "pin.h"
|
||||
|
||||
mp_obj_t pyb_gpio(uint n_args, mp_obj_t *args) {
|
||||
//assert(1 <= n_args && n_args <= 2);
|
||||
|
||||
const pin_obj_t *pin = pin_map_user_obj(args[0]);
|
||||
GPIO_TypeDef *port = pin->gpio;
|
||||
uint16_t pin_mask = pin->pin_mask;
|
||||
|
||||
if (n_args == 1) {
|
||||
// get pin
|
||||
if ((port->IDR & pin_mask) != (uint32_t)Bit_RESET) {
|
||||
return MP_OBJ_NEW_SMALL_INT(1);
|
||||
} else {
|
||||
return MP_OBJ_NEW_SMALL_INT(0);
|
||||
}
|
||||
} else {
|
||||
// set pin
|
||||
if (mp_obj_is_true(args[1])) {
|
||||
// set pin high
|
||||
port->BSRRL = pin_mask;
|
||||
} else {
|
||||
// set pin low
|
||||
port->BSRRH = pin_mask;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_obj, 1, 2, pyb_gpio);
|
||||
|
||||
mp_obj_t pyb_gpio_input(mp_obj_t arg_pin, mp_obj_t arg_mode) {
|
||||
const pin_obj_t *pin = pin_map_user_obj(arg_pin);
|
||||
GPIO_TypeDef *port = pin->gpio;
|
||||
uint16_t pin_mask = pin->pin_mask;
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = pin_mask;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_InitStructure.GPIO_PuPd = mp_obj_get_int(arg_mode);
|
||||
GPIO_Init(port, &GPIO_InitStructure);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(pyb_gpio_input_obj, pyb_gpio_input);
|
||||
|
||||
mp_obj_t pyb_gpio_output(mp_obj_t arg_pin, mp_obj_t arg_mode) {
|
||||
const pin_obj_t *pin = pin_map_user_obj(arg_pin);
|
||||
GPIO_TypeDef *port = pin->gpio;
|
||||
uint16_t pin_mask = pin->pin_mask;
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = pin_mask;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed;
|
||||
GPIO_InitStructure.GPIO_OType = mp_obj_get_int(arg_mode);
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(port, &GPIO_InitStructure);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(pyb_gpio_output_obj, pyb_gpio_output);
|
@ -1,5 +0,0 @@
|
||||
mp_obj_t pyb_gpio_input(mp_obj_t arg_pin, mp_obj_t arg_mode);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_gpio_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_gpio_input_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_gpio_output_obj);
|
364
stm/i2c.c
364
stm/i2c.c
@ -1,364 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stm32f4xx.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "systick.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
|
||||
typedef enum {
|
||||
PYB_I2C_1 = 0,
|
||||
PYB_I2C_2 = 1,
|
||||
} pyb_i2c_t;
|
||||
|
||||
typedef enum {
|
||||
I2C_STATE_IDLE = 0,
|
||||
I2C_STATE_WRITE = 1,
|
||||
I2C_STATE_READ = 2,
|
||||
} i2c_state_t;
|
||||
|
||||
// set to true if the port has already been initialized
|
||||
bool i2c1_port_initialized = false;
|
||||
bool i2c2_port_initialized = false;
|
||||
|
||||
static I2C_TypeDef * _i2c_port_addr(pyb_i2c_t i2c_port) {
|
||||
if (i2c_port == PYB_I2C_1) {
|
||||
return I2C1;
|
||||
}
|
||||
if (i2c_port == PYB_I2C_2) {
|
||||
return I2C2;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// todo - perhaps there should be some global resource management for gpio
|
||||
// this function would fail if the i2c pins have already been defined for
|
||||
// use by another python object
|
||||
// as it is, this always returns true (unless i2c_port is invalid)
|
||||
static bool _i2c_init(pyb_i2c_t i2c_port) {
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
I2C_TypeDef *i2c = _i2c_port_addr(i2c_port);
|
||||
if (i2c == NULL)
|
||||
return false;
|
||||
|
||||
if (i2c_port == PYB_I2C_1) {
|
||||
if (i2c1_port_initialized == true) {
|
||||
return true;
|
||||
}
|
||||
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // enable I2C1
|
||||
|
||||
// PB6=SCL, PB7=SDA
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
// alternate functions for SCL and SDA
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
|
||||
|
||||
|
||||
i2c1_port_initialized = true;
|
||||
}
|
||||
|
||||
if (i2c_port == PYB_I2C_2) {
|
||||
if (i2c2_port_initialized == true) {
|
||||
return true;
|
||||
}
|
||||
RCC->APB1ENR |= RCC_APB1ENR_I2C2EN; // enable I2C2
|
||||
|
||||
// PB10=SCL, PB11=SDA
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
// alternate functions for SCL and SDA
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2);
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2);
|
||||
|
||||
i2c2_port_initialized = true;
|
||||
}
|
||||
|
||||
// get clock speeds
|
||||
RCC_ClocksTypeDef rcc_clocks;
|
||||
RCC_GetClocksFreq(&rcc_clocks);
|
||||
|
||||
// disable the I2C peripheral before we configure it
|
||||
i2c->CR1 &= ~I2C_CR1_PE;
|
||||
|
||||
// program peripheral input clock
|
||||
i2c->CR2 = 4; // no interrupts; 4 MHz (hopefully!) (could go up to 42MHz)
|
||||
|
||||
// configure clock control reg
|
||||
uint32_t freq = rcc_clocks.PCLK1_Frequency / (100000 << 1); // want 100kHz, this is the formula for freq
|
||||
i2c->CCR = freq; // standard mode (speed), freq calculated as above
|
||||
|
||||
// configure rise time reg
|
||||
i2c->TRISE = (rcc_clocks.PCLK1_Frequency / 1000000) + 1; // formula for trise, gives maximum rise time
|
||||
|
||||
// enable the I2C peripheral
|
||||
i2c->CR1 |= I2C_CR1_PE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t _i2c_get_sr(pyb_i2c_t i2c_port) {
|
||||
// must read SR1 first, then SR2, as the read can clear some flags
|
||||
I2C_TypeDef *i2c = _i2c_port_addr(i2c_port);
|
||||
if (i2c == NULL) return 0;
|
||||
|
||||
uint32_t sr1 = i2c->SR1;
|
||||
uint32_t sr2 = i2c->SR2;
|
||||
return (sr2 << 16) | sr1;
|
||||
}
|
||||
|
||||
static bool _i2c_restart(pyb_i2c_t i2c_port, uint8_t addr, int write) {
|
||||
I2C_TypeDef *i2c = _i2c_port_addr(i2c_port);
|
||||
if (i2c == NULL) return false;
|
||||
|
||||
// send start condition
|
||||
i2c->CR1 |= I2C_CR1_START;
|
||||
|
||||
// wait for BUSY, MSL and SB --> Slave has acknowledged start condition
|
||||
uint32_t timeout = 1000000;
|
||||
while ((_i2c_get_sr(i2c_port) & 0x00030001) != 0x00030001) {
|
||||
if (--timeout == 0) {
|
||||
//printf("timeout in _i2c_restart\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (write) {
|
||||
// send address and write bit
|
||||
i2c->DR = (addr << 1) | 0;
|
||||
// wait for BUSY, MSL, ADDR, TXE and TRA
|
||||
timeout = 1000000;
|
||||
while ((_i2c_get_sr(i2c_port) & 0x00070082) != 0x00070082) {
|
||||
if (--timeout == 0) {
|
||||
//printf("timeout in _i2c_restart write\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// send address and read bit
|
||||
i2c->DR = (addr << 1) | 1;
|
||||
// wait for BUSY, MSL and ADDR flags
|
||||
timeout = 1000000;
|
||||
while ((_i2c_get_sr(i2c_port) & 0x00030002) != 0x00030002) {
|
||||
if (--timeout == 0) {
|
||||
//printf("timeout in _i2c_restart read\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _i2c_send_byte(pyb_i2c_t i2c_port, uint8_t data) {
|
||||
I2C_TypeDef *i2c = _i2c_port_addr(i2c_port);
|
||||
if (i2c == NULL) return false;
|
||||
|
||||
// send byte
|
||||
i2c->DR = data;
|
||||
// wait for TRA, BUSY, MSL, TXE and BTF (byte transmitted)
|
||||
uint32_t timeout = 1000000;
|
||||
while ((_i2c_get_sr(i2c_port) & 0x00070084) != 0x00070084) {
|
||||
if (--timeout == 0) {
|
||||
//printf("timeout in _i2c_send_byte\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t _i2c_read_ack(pyb_i2c_t i2c_port) {
|
||||
I2C_TypeDef *i2c = _i2c_port_addr(i2c_port);
|
||||
if (i2c == NULL) return 0;
|
||||
|
||||
// enable ACK of received byte
|
||||
i2c->CR1 |= I2C_CR1_ACK;
|
||||
// wait for BUSY, MSL and RXNE (byte received)
|
||||
uint32_t timeout = 1000000;
|
||||
while ((_i2c_get_sr(i2c_port) & 0x00030040) != 0x00030040) {
|
||||
if (--timeout == 0) {
|
||||
//printf("timeout in _i2c_read_ack\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// read and return data
|
||||
uint8_t data = i2c->DR;
|
||||
return data;
|
||||
}
|
||||
|
||||
static uint8_t _i2c_read_nack(pyb_i2c_t i2c_port) {
|
||||
I2C_TypeDef *i2c = _i2c_port_addr(i2c_port);
|
||||
if (i2c == NULL) return 0;
|
||||
|
||||
// disable ACK of received byte (to indicate end of receiving)
|
||||
i2c->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ACK);
|
||||
// last byte should apparently also generate a stop condition
|
||||
i2c->CR1 |= I2C_CR1_STOP;
|
||||
// wait for BUSY, MSL and RXNE (byte received)
|
||||
uint32_t timeout = 1000000;
|
||||
while ((_i2c_get_sr(i2c_port) & 0x00030040) != 0x00030040) {
|
||||
if (--timeout == 0) {
|
||||
//printf("timeout in _i2c_read_nack\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// read and return data
|
||||
uint8_t data = i2c->DR;
|
||||
return data;
|
||||
}
|
||||
|
||||
static bool _i2c_start(pyb_i2c_t i2c_port) {
|
||||
I2C_TypeDef *i2c = _i2c_port_addr(i2c_port);
|
||||
if (i2c == NULL) return false;
|
||||
|
||||
// wait until I2C is not busy
|
||||
uint32_t timeout = 1000000;
|
||||
while (i2c->SR2 & I2C_SR2_BUSY) {
|
||||
if (--timeout == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void _i2c_stop(pyb_i2c_t i2c_port) {
|
||||
I2C_TypeDef *i2c = _i2c_port_addr(i2c_port);
|
||||
if (i2c == NULL) return;
|
||||
|
||||
// send stop condition
|
||||
i2c->CR1 |= I2C_CR1_STOP;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
|
||||
typedef struct _pyb_i2c_obj_t {
|
||||
mp_obj_base_t base;
|
||||
pyb_i2c_t i2c_port;
|
||||
int i2c_addr;
|
||||
i2c_state_t i2c_state;
|
||||
} pyb_i2c_obj_t;
|
||||
|
||||
void i2c_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_i2c_obj_t *self = self_in;
|
||||
print(env, "<I2C%lu addr:%lu>", (unsigned int)self->i2c_port, (unsigned int)self->i2c_addr);
|
||||
}
|
||||
|
||||
// calls _i2c_start with write=0,1 depending on LSB of i2c_addr
|
||||
mp_obj_t i2c_obj_start(mp_obj_t self_in) {
|
||||
pyb_i2c_obj_t *self = self_in;
|
||||
if (self->i2c_state != I2C_STATE_IDLE) {
|
||||
_i2c_stop(self->i2c_port);
|
||||
self->i2c_state = I2C_STATE_IDLE;
|
||||
}
|
||||
if (_i2c_start(self->i2c_port) == true)
|
||||
return mp_const_true;
|
||||
return mp_const_false;
|
||||
}
|
||||
|
||||
mp_obj_t i2c_obj_write(mp_obj_t self_in, mp_obj_t data_in) {
|
||||
pyb_i2c_obj_t *self = self_in;
|
||||
if (self->i2c_state != I2C_STATE_WRITE) {
|
||||
if (_i2c_restart(self->i2c_port, self->i2c_addr, 1) == false) {
|
||||
_i2c_stop(self->i2c_port);
|
||||
self->i2c_state = I2C_STATE_IDLE;
|
||||
return mp_const_false;
|
||||
}
|
||||
self->i2c_state = I2C_STATE_WRITE;
|
||||
}
|
||||
uint8_t data = mp_obj_get_int(data_in);
|
||||
if (_i2c_send_byte(self->i2c_port, data) == false)
|
||||
return mp_const_false;
|
||||
return mp_const_true;
|
||||
}
|
||||
|
||||
mp_obj_t i2c_obj_read(mp_obj_t self_in) {
|
||||
pyb_i2c_obj_t *self = self_in;
|
||||
if (self->i2c_state != I2C_STATE_READ) {
|
||||
if (_i2c_restart(self->i2c_port, self->i2c_addr, 0) == false) {
|
||||
_i2c_stop(self->i2c_port);
|
||||
self->i2c_state = I2C_STATE_IDLE;
|
||||
return mp_const_false;
|
||||
}
|
||||
self->i2c_state = I2C_STATE_READ;
|
||||
}
|
||||
uint8_t data = _i2c_read_ack(self->i2c_port);
|
||||
return mp_obj_new_int(data);
|
||||
}
|
||||
|
||||
mp_obj_t i2c_obj_readAndStop(mp_obj_t self_in) {
|
||||
pyb_i2c_obj_t *self = self_in;
|
||||
if (self->i2c_state != I2C_STATE_READ) {
|
||||
if (_i2c_restart(self->i2c_port, self->i2c_addr, 0) == false) {
|
||||
_i2c_stop(self->i2c_port);
|
||||
self->i2c_state = I2C_STATE_IDLE;
|
||||
return mp_const_false;
|
||||
}
|
||||
}
|
||||
uint8_t data = _i2c_read_nack(self->i2c_port);
|
||||
self->i2c_state = I2C_STATE_IDLE;
|
||||
return mp_obj_new_int(data);
|
||||
}
|
||||
|
||||
mp_obj_t i2c_obj_stop(mp_obj_t self_in) {
|
||||
pyb_i2c_obj_t *self = self_in;
|
||||
_i2c_stop(self->i2c_port);
|
||||
self->i2c_state = I2C_STATE_IDLE;
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(i2c_obj_start_obj, i2c_obj_start);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(i2c_obj_write_obj, i2c_obj_write);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(i2c_obj_read_obj, i2c_obj_read);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(i2c_obj_readAndStop_obj, i2c_obj_readAndStop);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(i2c_obj_stop_obj, i2c_obj_stop);
|
||||
|
||||
STATIC const mp_map_elem_t i2c_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_start), (mp_obj_t)&i2c_obj_start_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&i2c_obj_write_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&i2c_obj_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readAndStop), (mp_obj_t)&i2c_obj_readAndStop_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stop), (mp_obj_t)&i2c_obj_stop_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(i2c_locals_dict, i2c_locals_dict_table);
|
||||
|
||||
static const mp_obj_type_t i2c_obj_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_I2C,
|
||||
.print = i2c_obj_print,
|
||||
.locals_dict = (mp_obj_t)&i2c_locals_dict,
|
||||
};
|
||||
|
||||
// create the I2C object
|
||||
// currently support either I2C1 (i2c_id = 0) or I2C2 (i2c_id = 1)
|
||||
|
||||
mp_obj_t pyb_I2C(mp_obj_t i2c_id, mp_obj_t i2c_addr) {
|
||||
pyb_i2c_t i2c_port;
|
||||
switch(mp_obj_get_int(i2c_id)) {
|
||||
case 0: i2c_port = PYB_I2C_1; break;
|
||||
case 1: i2c_port = PYB_I2C_2; break;
|
||||
default: return mp_const_none;
|
||||
}
|
||||
if (_i2c_init(i2c_port) == false) {
|
||||
return mp_const_none;
|
||||
}
|
||||
pyb_i2c_obj_t *o = m_new_obj(pyb_i2c_obj_t);
|
||||
o->base.type = &i2c_obj_type;
|
||||
o->i2c_port = i2c_port;
|
||||
o->i2c_addr = mp_obj_get_int(i2c_addr);
|
||||
o->i2c_state = I2C_STATE_IDLE;
|
||||
return o;
|
||||
}
|
20
stm/import.c
20
stm/import.c
@ -1,20 +0,0 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "ff.h"
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
FILINFO fno;
|
||||
FRESULT res = f_stat(path, &fno);
|
||||
if (res == FR_OK) {
|
||||
if ((fno.fattrib & AM_DIR) != 0) {
|
||||
return MP_IMPORT_STAT_DIR;
|
||||
} else {
|
||||
return MP_IMPORT_STAT_FILE;
|
||||
}
|
||||
}
|
||||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
385
stm/lcd.c
385
stm/lcd.c
@ -1,385 +0,0 @@
|
||||
#include <string.h>
|
||||
#include <stm32f4xx_gpio.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
|
||||
#if MICROPY_HW_HAS_LCD
|
||||
|
||||
#include "qstr.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
#include "systick.h"
|
||||
#include "font_petme128_8x8.h"
|
||||
#include "lcd.h"
|
||||
|
||||
#if defined(PYBOARD3)
|
||||
#define PYB_LCD_PORT (GPIOA)
|
||||
#define PYB_LCD_CS1_PIN (GPIO_Pin_0)
|
||||
#define PYB_LCD_RST_PIN (GPIO_Pin_1)
|
||||
#define PYB_LCD_A0_PIN (GPIO_Pin_2)
|
||||
#define PYB_LCD_SCL_PIN (GPIO_Pin_3)
|
||||
#define PYB_LCD_SI_PIN (GPIO_Pin_4)
|
||||
#elif defined(PYBOARD4)
|
||||
// X position
|
||||
#define PYB_LCD_PORT (GPIOA)
|
||||
#define PYB_LCD_CS1_PIN (GPIO_Pin_2) // X3
|
||||
#define PYB_LCD_RST_PIN (GPIO_Pin_3) // X4
|
||||
#define PYB_LCD_A0_PIN (GPIO_Pin_4) // X5
|
||||
#define PYB_LCD_SCL_PIN (GPIO_Pin_5) // X6
|
||||
#define PYB_LCD_SI_PIN (GPIO_Pin_7) // X8
|
||||
#define PYB_LCD_BL_PORT (GPIOC)
|
||||
#define PYB_LCD_BL_PIN (GPIO_Pin_5) // X12
|
||||
/*
|
||||
// Y position
|
||||
#define PYB_LCD_PORT (GPIOB)
|
||||
#define PYB_LCD_CS1_PIN (GPIO_Pin_8) // Y3 = PB8
|
||||
#define PYB_LCD_RST_PIN (GPIO_Pin_9) // Y4 = PB9
|
||||
#define PYB_LCD_A0_PIN (GPIO_Pin_12) // Y5 = PB12
|
||||
#define PYB_LCD_SCL_PIN (GPIO_Pin_13) // Y6 = PB13
|
||||
#define PYB_LCD_SI_PIN (GPIO_Pin_15) // Y8 = PB15
|
||||
#define PYB_LCD_BL_PORT (GPIOB)
|
||||
#define PYB_LCD_BL_PIN (GPIO_Pin_1) // Y12 = PB1
|
||||
*/
|
||||
#elif defined(STM32F4DISC)
|
||||
/* Configure if needed */
|
||||
#define PYB_LCD_PORT (GPIOA)
|
||||
#define PYB_LCD_CS1_PIN (GPIO_Pin_2) // X3
|
||||
#define PYB_LCD_RST_PIN (GPIO_Pin_3) // X4
|
||||
#define PYB_LCD_A0_PIN (GPIO_Pin_4) // X5
|
||||
#define PYB_LCD_SCL_PIN (GPIO_Pin_5) // X6
|
||||
#define PYB_LCD_SI_PIN (GPIO_Pin_7) // X8
|
||||
#define PYB_LCD_BL_PORT (GPIOC)
|
||||
#define PYB_LCD_BL_PIN (GPIO_Pin_5) // X12
|
||||
#endif
|
||||
|
||||
#define LCD_INSTR (0)
|
||||
#define LCD_DATA (1)
|
||||
|
||||
static void lcd_out(int instr_data, uint8_t i) {
|
||||
sys_tick_delay_ms(0);
|
||||
PYB_LCD_PORT->BSRRH = PYB_LCD_CS1_PIN; // CS=0; enable
|
||||
if (instr_data == LCD_INSTR) {
|
||||
PYB_LCD_PORT->BSRRH = PYB_LCD_A0_PIN; // A0=0; select instr reg
|
||||
} else {
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_A0_PIN; // A0=1; select data reg
|
||||
}
|
||||
// send byte bigendian, latches on rising clock
|
||||
for (uint32_t n = 0; n < 8; n++) {
|
||||
sys_tick_delay_ms(0);
|
||||
PYB_LCD_PORT->BSRRH = PYB_LCD_SCL_PIN; // SCL=0
|
||||
if ((i & 0x80) == 0) {
|
||||
PYB_LCD_PORT->BSRRH = PYB_LCD_SI_PIN; // SI=0
|
||||
} else {
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_SI_PIN; // SI=1
|
||||
}
|
||||
i <<= 1;
|
||||
sys_tick_delay_ms(0);
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_SCL_PIN; // SCL=1
|
||||
}
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_CS1_PIN; // CS=1; disable
|
||||
|
||||
/*
|
||||
in Python, native types:
|
||||
CS1_PIN(const) = 0
|
||||
n = int(0)
|
||||
delay_ms(0)
|
||||
PORT[word:BSRRH] = 1 << CS1_PIN
|
||||
for n in range(0, 8):
|
||||
delay_ms(0)
|
||||
PORT[word:BSRRH] = 1 << SCL_PIN
|
||||
if i & 0x80 == 0:
|
||||
PORT[word:BSRRH] = 1 << SI_PIN
|
||||
else:
|
||||
PORT[word:BSRRL] = 1 << SI_PIN
|
||||
i <<= 1
|
||||
delay_ms(0)
|
||||
PORT[word:BSRRL] = 1 << SCL_PIN
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
static void lcd_data_out(uint8_t i) {
|
||||
delay_ms(0);
|
||||
PYB_LCD_PORT->BSRRH = PYB_LCD_CS1_PIN; // CS=0; enable
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_A0_PIN; // A0=1; select data reg
|
||||
// send byte bigendian, latches on rising clock
|
||||
for (uint32_t n = 0; n < 8; n++) {
|
||||
delay_ms(0);
|
||||
PYB_LCD_PORT->BSRRH = PYB_LCD_SCL_PIN; // SCL=0
|
||||
if ((i & 0x80) == 0) {
|
||||
PYB_LCD_PORT->BSRRH = PYB_LCD_SI_PIN; // SI=0
|
||||
} else {
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_SI_PIN; // SI=1
|
||||
}
|
||||
i <<= 1;
|
||||
delay_ms(0);
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_SCL_PIN; // SCL=1
|
||||
}
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_CS1_PIN; // CS=1; disable
|
||||
}
|
||||
*/
|
||||
|
||||
// writes 8 vertical pixels
|
||||
// pos 0 is upper left, pos 1 is 8 pixels to right of that, pos 128 is 8 pixels below that
|
||||
mp_obj_t lcd_draw_pixel_8(mp_obj_t mp_pos, mp_obj_t mp_val) {
|
||||
int pos = mp_obj_get_int(mp_pos);
|
||||
int val = mp_obj_get_int(mp_val);
|
||||
int page = pos / 128;
|
||||
int offset = pos - (page * 128);
|
||||
lcd_out(LCD_INSTR, 0xb0 | page); // page address set
|
||||
lcd_out(LCD_INSTR, 0x10 | ((offset >> 4) & 0x0f)); // column address set upper
|
||||
lcd_out(LCD_INSTR, 0x00 | (offset & 0x0f)); // column address set lower
|
||||
lcd_out(LCD_DATA, val); // write data
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
#define LCD_BUF_W (16)
|
||||
#define LCD_BUF_H (4)
|
||||
|
||||
char lcd_char_buffer[LCD_BUF_W * LCD_BUF_H];
|
||||
int lcd_line;
|
||||
int lcd_column;
|
||||
int lcd_next_line;
|
||||
|
||||
#define LCD_PIX_BUF_SIZE (128 * 32 / 8)
|
||||
byte lcd_pix_buf[LCD_PIX_BUF_SIZE];
|
||||
byte lcd_pix_buf2[LCD_PIX_BUF_SIZE];
|
||||
|
||||
mp_obj_t lcd_pix_clear(void) {
|
||||
memset(lcd_pix_buf, 0, LCD_PIX_BUF_SIZE);
|
||||
memset(lcd_pix_buf2, 0, LCD_PIX_BUF_SIZE);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t lcd_pix_get(mp_obj_t mp_x, mp_obj_t mp_y) {
|
||||
int x = mp_obj_get_int(mp_x);
|
||||
int y = mp_obj_get_int(mp_y);
|
||||
if (0 <= x && x <= 127 && 0 <= y && y <= 31) {
|
||||
uint byte_pos = x + 128 * ((uint)y >> 3);
|
||||
if (lcd_pix_buf[byte_pos] & (1 << (y & 7))) {
|
||||
return mp_obj_new_int(1);
|
||||
}
|
||||
}
|
||||
return mp_obj_new_int(0);
|
||||
}
|
||||
|
||||
mp_obj_t lcd_pix_set(mp_obj_t mp_x, mp_obj_t mp_y) {
|
||||
int x = mp_obj_get_int(mp_x);
|
||||
int y = mp_obj_get_int(mp_y);
|
||||
if (0 <= x && x <= 127 && 0 <= y && y <= 31) {
|
||||
uint byte_pos = x + 128 * ((uint)y >> 3);
|
||||
lcd_pix_buf2[byte_pos] |= 1 << (y & 7);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t lcd_pix_reset(mp_obj_t mp_x, mp_obj_t mp_y) {
|
||||
int x = mp_obj_get_int(mp_x);
|
||||
int y = mp_obj_get_int(mp_y);
|
||||
if (0 <= x && x <= 127 && 0 <= y && y <= 31) {
|
||||
uint byte_pos = x + 128 * ((uint)y >> 3);
|
||||
lcd_pix_buf2[byte_pos] &= ~(1 << (y & 7));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t lcd_pix_show(void) {
|
||||
memcpy(lcd_pix_buf, lcd_pix_buf2, LCD_PIX_BUF_SIZE);
|
||||
for (uint page = 0; page < 4; page++) {
|
||||
lcd_out(LCD_INSTR, 0xb0 | page); // page address set
|
||||
lcd_out(LCD_INSTR, 0x10); // column address set upper; 0
|
||||
lcd_out(LCD_INSTR, 0x00); // column address set lower; 0
|
||||
for (uint i = 0; i < 128; i++) {
|
||||
lcd_out(LCD_DATA, lcd_pix_buf[i + 128 * page]);
|
||||
}
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t lcd_print(mp_obj_t text) {
|
||||
uint len;
|
||||
const char *data = mp_obj_str_get_data(text, &len);
|
||||
lcd_print_strn(data, len);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t lcd_light(mp_obj_t value) {
|
||||
#if defined(PYB_LCD_BL_PORT)
|
||||
if (mp_obj_is_true(value)) {
|
||||
PYB_LCD_BL_PORT->BSRRL = PYB_LCD_BL_PIN; // set pin high to turn backlight on
|
||||
} else {
|
||||
PYB_LCD_BL_PORT->BSRRH = PYB_LCD_BL_PIN; // set pin low to turn backlight off
|
||||
}
|
||||
#endif
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static mp_obj_t mp_lcd = MP_OBJ_NULL;
|
||||
|
||||
static mp_obj_t pyb_lcd_init(void) {
|
||||
if (mp_lcd != MP_OBJ_NULL) {
|
||||
// already init'd
|
||||
return mp_lcd;
|
||||
}
|
||||
|
||||
// set the outputs high
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_CS1_PIN;
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_RST_PIN;
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_A0_PIN;
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_SCL_PIN;
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_SI_PIN;
|
||||
|
||||
// make them push/pull outputs
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = PYB_LCD_CS1_PIN | PYB_LCD_RST_PIN | PYB_LCD_A0_PIN | PYB_LCD_SCL_PIN | PYB_LCD_SI_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(PYB_LCD_PORT, &GPIO_InitStructure);
|
||||
|
||||
#if defined(PYB_LCD_BL_PORT)
|
||||
// backlight drive pin, starts low (off)
|
||||
PYB_LCD_BL_PORT->BSRRH = PYB_LCD_BL_PIN;
|
||||
GPIO_InitStructure.GPIO_Pin = PYB_LCD_BL_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(PYB_LCD_BL_PORT, &GPIO_InitStructure);
|
||||
#endif
|
||||
|
||||
// init the LCD
|
||||
sys_tick_delay_ms(1); // wait a bit
|
||||
PYB_LCD_PORT->BSRRH = PYB_LCD_RST_PIN; // RST=0; reset
|
||||
sys_tick_delay_ms(1); // wait for reset; 2us min
|
||||
PYB_LCD_PORT->BSRRL = PYB_LCD_RST_PIN; // RST=1; enable
|
||||
sys_tick_delay_ms(1); // wait for reset; 2us min
|
||||
lcd_out(LCD_INSTR, 0xa0); // ADC select, normal
|
||||
lcd_out(LCD_INSTR, 0xc8); // common output mode select, reverse
|
||||
lcd_out(LCD_INSTR, 0xa2); // LCD bias set, 1/9 bias
|
||||
lcd_out(LCD_INSTR, 0x2f); // power control set, 0b111=(booster on, vreg on, vfollow on)
|
||||
lcd_out(LCD_INSTR, 0x21); // v0 voltage regulator internal resistor ratio set, 0b001=small
|
||||
lcd_out(LCD_INSTR, 0x81); // electronic volume mode set
|
||||
lcd_out(LCD_INSTR, 0x34); // electronic volume register set, 0b110100
|
||||
lcd_out(LCD_INSTR, 0x40); // display start line set, 0
|
||||
lcd_out(LCD_INSTR, 0xaf); // LCD display, on
|
||||
|
||||
// clear display
|
||||
for (int page = 0; page < 4; page++) {
|
||||
lcd_out(LCD_INSTR, 0xb0 | page); // page address set
|
||||
lcd_out(LCD_INSTR, 0x10); // column address set upper
|
||||
lcd_out(LCD_INSTR, 0x00); // column address set lower
|
||||
for (int i = 0; i < 128; i++) {
|
||||
lcd_out(LCD_DATA, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < LCD_BUF_H * LCD_BUF_W; i++) {
|
||||
lcd_char_buffer[i] = ' ';
|
||||
}
|
||||
lcd_line = 0;
|
||||
lcd_column = 0;
|
||||
lcd_next_line = 0;
|
||||
|
||||
// Micro Python interface
|
||||
mp_obj_t o = mp_obj_new_type(MP_QSTR_LCD, mp_const_empty_tuple, mp_obj_new_dict(0));
|
||||
mp_store_attr(o, qstr_from_str("lcd8"), mp_make_function_n(2, lcd_draw_pixel_8));
|
||||
mp_store_attr(o, qstr_from_str("clear"), mp_make_function_n(0, lcd_pix_clear));
|
||||
mp_store_attr(o, qstr_from_str("get"), mp_make_function_n(2, lcd_pix_get));
|
||||
mp_store_attr(o, qstr_from_str("set"), mp_make_function_n(2, lcd_pix_set));
|
||||
mp_store_attr(o, qstr_from_str("reset"), mp_make_function_n(2, lcd_pix_reset));
|
||||
mp_store_attr(o, qstr_from_str("show"), mp_make_function_n(0, lcd_pix_show));
|
||||
mp_store_attr(o, qstr_from_str("text"), mp_make_function_n(1, lcd_print));
|
||||
mp_store_attr(o, qstr_from_str("light"), mp_make_function_n(1, lcd_light));
|
||||
mp_lcd = o;
|
||||
return o;
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_0(pyb_lcd_init_obj, pyb_lcd_init);
|
||||
|
||||
void lcd_init(void) {
|
||||
mp_lcd = MP_OBJ_NULL;
|
||||
mp_store_name(qstr_from_str("LCD"), (mp_obj_t)&pyb_lcd_init_obj);
|
||||
}
|
||||
|
||||
void lcd_print_str(const char *str) {
|
||||
lcd_print_strn(str, strlen(str));
|
||||
}
|
||||
|
||||
void lcd_print_strn(const char *str, unsigned int len) {
|
||||
int redraw_min = lcd_line * LCD_BUF_W + lcd_column;
|
||||
int redraw_max = redraw_min;
|
||||
int did_new_line = 0;
|
||||
for (; len > 0; len--, str++) {
|
||||
// move to next line if needed
|
||||
if (lcd_next_line) {
|
||||
if (lcd_line + 1 < LCD_BUF_H) {
|
||||
lcd_line += 1;
|
||||
} else {
|
||||
lcd_line = LCD_BUF_H - 1;
|
||||
for (int i = 0; i < LCD_BUF_W * (LCD_BUF_H - 1); i++) {
|
||||
lcd_char_buffer[i] = lcd_char_buffer[i + LCD_BUF_W];
|
||||
}
|
||||
for (int i = 0; i < LCD_BUF_W; i++) {
|
||||
lcd_char_buffer[LCD_BUF_W * (LCD_BUF_H - 1) + i] = ' ';
|
||||
}
|
||||
redraw_min = 0;
|
||||
redraw_max = LCD_BUF_W * LCD_BUF_H;
|
||||
}
|
||||
lcd_next_line = 0;
|
||||
lcd_column = 0;
|
||||
did_new_line = 1;
|
||||
}
|
||||
if (*str == '\n') {
|
||||
lcd_next_line = 1;
|
||||
} else if (*str == '\r') {
|
||||
lcd_column = 0;
|
||||
} else if (*str == '\b') {
|
||||
if (lcd_column > 0) {
|
||||
lcd_column--;
|
||||
}
|
||||
} else if (lcd_column >= LCD_BUF_W) {
|
||||
lcd_next_line = 1;
|
||||
str -= 1;
|
||||
len += 1;
|
||||
} else {
|
||||
lcd_char_buffer[lcd_line * LCD_BUF_W + lcd_column] = *str;
|
||||
lcd_column += 1;
|
||||
int max = lcd_line * LCD_BUF_W + lcd_column;
|
||||
if (max > redraw_max) {
|
||||
redraw_max = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int last_page = -1;
|
||||
for (int i = redraw_min; i < redraw_max; i++) {
|
||||
int page = i / LCD_BUF_W;
|
||||
if (page != last_page) {
|
||||
int offset = 8 * (i - (page * LCD_BUF_W));
|
||||
lcd_out(LCD_INSTR, 0xb0 | page); // page address set
|
||||
lcd_out(LCD_INSTR, 0x10 | ((offset >> 4) & 0x0f)); // column address set upper
|
||||
lcd_out(LCD_INSTR, 0x00 | (offset & 0x0f)); // column address set lower
|
||||
last_page = page;
|
||||
}
|
||||
int chr = lcd_char_buffer[i];
|
||||
if (chr < 32 || chr > 126) {
|
||||
chr = 127;
|
||||
}
|
||||
const uint8_t *chr_data = &font_petme128_8x8[(chr - 32) * 8];
|
||||
for (int j = 0; j < 8; j++) {
|
||||
lcd_out(LCD_DATA, chr_data[j]);
|
||||
}
|
||||
}
|
||||
|
||||
if (did_new_line) {
|
||||
sys_tick_delay_ms(50);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MICROPY_HW_HAS_LCD
|
@ -1,3 +0,0 @@
|
||||
void lcd_init(void);
|
||||
void lcd_print_str(const char *str);
|
||||
void lcd_print_strn(const char *str, unsigned int len);
|
134
stm/led.c
134
stm/led.c
@ -1,134 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_gpio.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "led.h"
|
||||
#include "pin.h"
|
||||
#include "build/pins.h"
|
||||
|
||||
static const pin_obj_t *gLed[] = {
|
||||
&PYB_LED1,
|
||||
#if defined(PYB_LED2)
|
||||
&PYB_LED2,
|
||||
#if defined(PYB_LED3)
|
||||
&PYB_LED3,
|
||||
#if defined(PYB_LED4)
|
||||
&PYB_LED4,
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
#define NUM_LEDS (sizeof(gLed) / sizeof(gLed[0]))
|
||||
|
||||
void led_init(void) {
|
||||
/* GPIO structure */
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
/* Configure I/O speed, mode, output type and pull */
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_InitStructure.GPIO_OType = PYB_OTYPE;
|
||||
|
||||
/* Turn off LEDs and initialize */
|
||||
for (int led = 0; led < NUM_LEDS; led++) {
|
||||
PYB_LED_OFF(gLed[led]);
|
||||
GPIO_InitStructure.GPIO_Pin = gLed[led]->pin_mask;
|
||||
GPIO_Init(gLed[led]->gpio, &GPIO_InitStructure);
|
||||
}
|
||||
}
|
||||
|
||||
void led_state(pyb_led_t led, int state) {
|
||||
if (led < 1 || led > NUM_LEDS) {
|
||||
return;
|
||||
}
|
||||
const pin_obj_t *led_pin = gLed[led - 1];
|
||||
if (state == 0) {
|
||||
// turn LED off
|
||||
PYB_LED_OFF(led_pin);
|
||||
} else {
|
||||
// turn LED on
|
||||
PYB_LED_ON(led_pin);
|
||||
}
|
||||
}
|
||||
|
||||
void led_toggle(pyb_led_t led) {
|
||||
if (led < 1 || led > NUM_LEDS) {
|
||||
return;
|
||||
}
|
||||
const pin_obj_t *led_pin = gLed[led - 1];
|
||||
GPIO_TypeDef *gpio = led_pin->gpio;
|
||||
|
||||
// We don't know if we're turning the LED on or off, but we don't really
|
||||
// care. Just invert the state.
|
||||
if (gpio->ODR & led_pin->pin_mask) {
|
||||
// pin is high, make it low
|
||||
gpio->BSRRH = led_pin->pin_mask;
|
||||
} else {
|
||||
// pin is low, make it high
|
||||
gpio->BSRRL = led_pin->pin_mask;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
|
||||
typedef struct _pyb_led_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint led_id;
|
||||
} pyb_led_obj_t;
|
||||
|
||||
void led_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_led_obj_t *self = self_in;
|
||||
print(env, "<LED %lu>", self->led_id);
|
||||
}
|
||||
|
||||
mp_obj_t led_obj_on(mp_obj_t self_in) {
|
||||
pyb_led_obj_t *self = self_in;
|
||||
led_state(self->led_id, 1);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t led_obj_off(mp_obj_t self_in) {
|
||||
pyb_led_obj_t *self = self_in;
|
||||
led_state(self->led_id, 0);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t led_obj_toggle(mp_obj_t self_in) {
|
||||
pyb_led_obj_t *self = self_in;
|
||||
led_toggle(self->led_id);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_toggle_obj, led_obj_toggle);
|
||||
|
||||
STATIC const mp_map_elem_t led_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_on), (mp_obj_t)&led_obj_on_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_off), (mp_obj_t)&led_obj_off_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_toggle), (mp_obj_t)&led_obj_toggle_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table);
|
||||
|
||||
static const mp_obj_type_t led_obj_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_Led,
|
||||
.print = led_obj_print,
|
||||
.locals_dict = (mp_obj_t)&led_locals_dict,
|
||||
};
|
||||
|
||||
static mp_obj_t pyb_Led(mp_obj_t led_id) {
|
||||
pyb_led_obj_t *o = m_new_obj(pyb_led_obj_t);
|
||||
o->base.type = &led_obj_type;
|
||||
o->led_id = mp_obj_get_int(led_id);
|
||||
return o;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(pyb_Led_obj, pyb_Led);
|
23
stm/led.h
23
stm/led.h
@ -1,23 +0,0 @@
|
||||
typedef enum {
|
||||
// PYBv3
|
||||
PYB_LED_R1 = 1,
|
||||
PYB_LED_R2 = 2,
|
||||
PYB_LED_G1 = 3,
|
||||
PYB_LED_G2 = 4,
|
||||
// PYBv4
|
||||
PYB_LED_RED = 1,
|
||||
PYB_LED_GREEN = 2,
|
||||
PYB_LED_YELLOW = 3,
|
||||
PYB_LED_BLUE = 4,
|
||||
//STM32F4DISC
|
||||
PYB_LED_R = 1,
|
||||
PYB_LED_G = 2,
|
||||
PYB_LED_B = 3,
|
||||
PYB_LED_O = 4,
|
||||
} pyb_led_t;
|
||||
|
||||
void led_init(void);
|
||||
void led_state(pyb_led_t led, int state);
|
||||
void led_toggle(pyb_led_t led);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_Led_obj);
|
@ -1,53 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "lexerfatfs.h"
|
||||
|
||||
typedef struct _mp_lexer_file_buf_t {
|
||||
FIL fp;
|
||||
char buf[20];
|
||||
uint16_t len;
|
||||
uint16_t pos;
|
||||
} mp_lexer_file_buf_t;
|
||||
|
||||
static unichar file_buf_next_char(mp_lexer_file_buf_t *fb) {
|
||||
if (fb->pos >= fb->len) {
|
||||
if (fb->len < sizeof(fb->buf)) {
|
||||
return MP_LEXER_CHAR_EOF;
|
||||
} else {
|
||||
UINT n;
|
||||
f_read(&fb->fp, fb->buf, sizeof(fb->buf), &n);
|
||||
if (n == 0) {
|
||||
return MP_LEXER_CHAR_EOF;
|
||||
}
|
||||
fb->len = n;
|
||||
fb->pos = 0;
|
||||
}
|
||||
}
|
||||
return fb->buf[fb->pos++];
|
||||
}
|
||||
|
||||
static void file_buf_close(mp_lexer_file_buf_t *fb) {
|
||||
f_close(&fb->fp);
|
||||
m_del_obj(mp_lexer_file_buf_t, fb);
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
mp_lexer_file_buf_t *fb = m_new_obj(mp_lexer_file_buf_t);
|
||||
FRESULT res = f_open(&fb->fp, filename, FA_READ);
|
||||
if (res != FR_OK) {
|
||||
m_del_obj(mp_lexer_file_buf_t, fb);
|
||||
return NULL;
|
||||
}
|
||||
UINT n;
|
||||
f_read(&fb->fp, fb->buf, sizeof(fb->buf), &n);
|
||||
fb->len = n;
|
||||
fb->pos = 0;
|
||||
return mp_lexer_new(qstr_from_str(filename), fb, (mp_lexer_stream_next_char_t)file_buf_next_char, (mp_lexer_stream_close_t)file_buf_close);
|
||||
}
|
@ -1 +0,0 @@
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename);
|
480
stm/main.c
480
stm/main.c
@ -1,480 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_rcc.h>
|
||||
#include <stm32f4xx_syscfg.h>
|
||||
#include <stm32f4xx_gpio.h>
|
||||
#include <stm32f4xx_exti.h>
|
||||
#include <stm32f4xx_tim.h>
|
||||
#include <stm32f4xx_pwr.h>
|
||||
#include <stm32f4xx_rtc.h>
|
||||
#include <stm32f4xx_usart.h>
|
||||
#include <stm32f4xx_rng.h>
|
||||
#include <usbd_storage_msd.h>
|
||||
#include <stm_misc.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "misc.h"
|
||||
#include "ff.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "lexer.h"
|
||||
#include "lexerfatfs.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "objmodule.h"
|
||||
#include "parsehelper.h"
|
||||
#include "compile.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
#include "gc.h"
|
||||
#include "gccollect.h"
|
||||
#include "systick.h"
|
||||
#include "pendsv.h"
|
||||
#include "pyexec.h"
|
||||
#include "led.h"
|
||||
#include "servo.h"
|
||||
#include "lcd.h"
|
||||
#include "storage.h"
|
||||
#include "sdcard.h"
|
||||
#include "accel.h"
|
||||
#include "usb.h"
|
||||
#include "timer.h"
|
||||
#include "pybwlan.h"
|
||||
#include "usrsw.h"
|
||||
#include "rtc.h"
|
||||
#include "file.h"
|
||||
#include "pin.h"
|
||||
#include "exti.h"
|
||||
#include "pybmodule.h"
|
||||
|
||||
int errno;
|
||||
|
||||
static FATFS fatfs0;
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
static FATFS fatfs1;
|
||||
#endif
|
||||
|
||||
void flash_error(int n) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
led_state(PYB_LED_R1, 1);
|
||||
led_state(PYB_LED_R2, 0);
|
||||
sys_tick_delay_ms(250);
|
||||
led_state(PYB_LED_R1, 0);
|
||||
led_state(PYB_LED_R2, 1);
|
||||
sys_tick_delay_ms(250);
|
||||
}
|
||||
led_state(PYB_LED_R2, 0);
|
||||
}
|
||||
|
||||
void __fatal_error(const char *msg) {
|
||||
#if MICROPY_HW_HAS_LCD
|
||||
lcd_print_strn("\nFATAL ERROR:\n", 14);
|
||||
lcd_print_strn(msg, strlen(msg));
|
||||
#endif
|
||||
for (;;) {
|
||||
flash_error(1);
|
||||
}
|
||||
}
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
printf("FATAL: uncaught exception %p\n", val);
|
||||
__fatal_error("");
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_config_source_dir = MP_OBJ_NULL;
|
||||
STATIC mp_obj_t pyb_config_main = MP_OBJ_NULL;
|
||||
|
||||
STATIC mp_obj_t pyb_source_dir(mp_obj_t source_dir) {
|
||||
if (MP_OBJ_IS_STR(source_dir)) {
|
||||
pyb_config_source_dir = source_dir;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(pyb_source_dir_obj, pyb_source_dir);
|
||||
|
||||
STATIC mp_obj_t pyb_main(mp_obj_t main) {
|
||||
if (MP_OBJ_IS_STR(main)) {
|
||||
pyb_config_main = main;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(pyb_main_obj, pyb_main);
|
||||
|
||||
void fatality(void) {
|
||||
led_state(PYB_LED_R1, 1);
|
||||
led_state(PYB_LED_G1, 1);
|
||||
led_state(PYB_LED_R2, 1);
|
||||
led_state(PYB_LED_G2, 1);
|
||||
}
|
||||
|
||||
static const char fresh_boot_py[] =
|
||||
"# boot.py -- run on boot-up\n"
|
||||
"# can run arbitrary Python, but best to keep it minimal\n"
|
||||
"\n"
|
||||
"pyb.source_dir('/src')\n"
|
||||
"pyb.main('main.py')\n"
|
||||
"#pyb.usb_usr('VCP')\n"
|
||||
"#pyb.usb_msd(True, 'dual partition')\n"
|
||||
"#pyb.flush_cache(False)\n"
|
||||
"#pyb.error_log('error.txt')\n"
|
||||
;
|
||||
|
||||
static const char fresh_main_py[] =
|
||||
"# main.py -- put your code here!\n"
|
||||
;
|
||||
|
||||
static const char *help_text =
|
||||
"Welcome to Micro Python!\n\n"
|
||||
"This is a *very* early version of Micro Python and has minimal functionality.\n\n"
|
||||
"Specific commands for the board:\n"
|
||||
" pyb.info() -- print some general information\n"
|
||||
" pyb.gc() -- run the garbage collector\n"
|
||||
" pyb.repl_info(<val>) -- enable/disable printing of info after each command\n"
|
||||
" pyb.delay(<n>) -- wait for n milliseconds\n"
|
||||
" pyb.udelay(<n>) -- wait for n microseconds\n"
|
||||
" pyb.Led(<n>) -- create Led object for LED n (n=1,2)\n"
|
||||
" Led methods: on(), off()\n"
|
||||
" pyb.Servo(<n>) -- create Servo object for servo n (n=1,2,3,4)\n"
|
||||
" Servo methods: angle(<x>)\n"
|
||||
" pyb.switch() -- return True/False if switch pressed or not\n"
|
||||
" pyb.accel() -- get accelerometer values\n"
|
||||
" pyb.rand() -- get a 16-bit random number\n"
|
||||
" pyb.gpio(<port>) -- get port value (port='A4' for example)\n"
|
||||
" pyb.gpio(<port>, <val>) -- set port value, True or False, 1 or 0\n"
|
||||
" pyb.ADC(<port>) -- make an analog port object (port='C0' for example)\n"
|
||||
" ADC methods: read()\n"
|
||||
;
|
||||
|
||||
// get some help about available functions
|
||||
static mp_obj_t pyb_help(void) {
|
||||
printf("%s", help_text);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
// TODO disable JTAG
|
||||
|
||||
// update the SystemCoreClock variable
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
// set interrupt priority config to use all 4 bits for pre-empting
|
||||
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
|
||||
|
||||
// enable the CCM RAM and the GPIO's
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN | RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN;
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
{
|
||||
// configure SDIO pins to be high to start with (apparently makes it more robust)
|
||||
// FIXME this is not making them high, it just makes them outputs...
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
|
||||
// Configure PD.02 CMD line
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
|
||||
GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||||
}
|
||||
#endif
|
||||
#if defined(NETDUINO_PLUS_2)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
// Turn on the power enable for the sdcard (PB1)
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
GPIO_WriteBit(GPIOB, GPIO_Pin_1, Bit_SET);
|
||||
#endif
|
||||
|
||||
// Turn on the power for the 5V on the expansion header (PB2)
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
GPIO_WriteBit(GPIOB, GPIO_Pin_2, Bit_SET);
|
||||
}
|
||||
#endif
|
||||
|
||||
// basic sub-system init
|
||||
sys_tick_init();
|
||||
pendsv_init();
|
||||
led_init();
|
||||
|
||||
#if MICROPY_HW_ENABLE_RTC
|
||||
rtc_init();
|
||||
#endif
|
||||
|
||||
// turn on LED to indicate bootup
|
||||
led_state(PYB_LED_G1, 1);
|
||||
|
||||
// more sub-system init
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
sdcard_init();
|
||||
#endif
|
||||
storage_init();
|
||||
|
||||
// uncomment these 2 lines if you want REPL on USART_6 (or another usart) as well as on USB VCP
|
||||
//pyb_usart_global_debug = PYB_USART_YA;
|
||||
//usart_init(pyb_usart_global_debug, 115200);
|
||||
|
||||
int first_soft_reset = true;
|
||||
|
||||
soft_reset:
|
||||
|
||||
// GC init
|
||||
gc_init(&_heap_start, &_heap_end);
|
||||
|
||||
// Micro Python init
|
||||
qstr_init();
|
||||
mp_init();
|
||||
mp_obj_list_init(mp_sys_path, 0);
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_lib));
|
||||
mp_obj_list_init(mp_sys_argv, 0);
|
||||
|
||||
exti_init();
|
||||
|
||||
#if MICROPY_HW_HAS_SWITCH
|
||||
switch_init();
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_HAS_LCD
|
||||
// LCD init (just creates class, init hardware by calling LCD())
|
||||
lcd_init();
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_ENABLE_SERVO
|
||||
// servo
|
||||
servo_init();
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_ENABLE_TIMER
|
||||
// timer
|
||||
timer_init();
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
// RNG
|
||||
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
|
||||
RNG_Cmd(ENABLE);
|
||||
#endif
|
||||
|
||||
pin_map_init();
|
||||
|
||||
// add some functions to the builtin Python namespace
|
||||
mp_store_name(MP_QSTR_help, mp_make_function_n(0, pyb_help));
|
||||
mp_store_name(MP_QSTR_open, mp_make_function_n(2, pyb_io_open));
|
||||
|
||||
// load the pyb module
|
||||
mp_module_register(MP_QSTR_pyb, (mp_obj_t)&pyb_module);
|
||||
|
||||
// check if user switch held (initiates reset of filesystem)
|
||||
bool reset_filesystem = false;
|
||||
#if MICROPY_HW_HAS_SWITCH
|
||||
if (switch_get()) {
|
||||
reset_filesystem = true;
|
||||
for (int i = 0; i < 50; i++) {
|
||||
if (!switch_get()) {
|
||||
reset_filesystem = false;
|
||||
break;
|
||||
}
|
||||
sys_tick_delay_ms(10);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// local filesystem init
|
||||
{
|
||||
// try to mount the flash
|
||||
FRESULT res = f_mount(&fatfs0, "0:", 1);
|
||||
if (!reset_filesystem && res == FR_OK) {
|
||||
// mount sucessful
|
||||
} else if (reset_filesystem || res == FR_NO_FILESYSTEM) {
|
||||
// no filesystem, so create a fresh one
|
||||
// TODO doesn't seem to work correctly when reset_filesystem is true...
|
||||
|
||||
// LED on to indicate creation of LFS
|
||||
led_state(PYB_LED_R2, 1);
|
||||
uint32_t stc = sys_tick_counter;
|
||||
|
||||
res = f_mkfs("0:", 0, 0);
|
||||
if (res == FR_OK) {
|
||||
// success creating fresh LFS
|
||||
} else {
|
||||
__fatal_error("could not create LFS");
|
||||
}
|
||||
|
||||
// create src directory
|
||||
res = f_mkdir("0:/src");
|
||||
// ignore result from mkdir
|
||||
|
||||
// create empty main.py
|
||||
FIL fp;
|
||||
f_open(&fp, "0:/src/main.py", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
UINT n;
|
||||
f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n);
|
||||
// TODO check we could write n bytes
|
||||
f_close(&fp);
|
||||
|
||||
// keep LED on for at least 200ms
|
||||
sys_tick_wait_at_least(stc, 200);
|
||||
led_state(PYB_LED_R2, 0);
|
||||
} else {
|
||||
__fatal_error("could not access LFS");
|
||||
}
|
||||
}
|
||||
|
||||
// make sure we have a /boot.py
|
||||
{
|
||||
FILINFO fno;
|
||||
FRESULT res = f_stat("0:/boot.py", &fno);
|
||||
if (res == FR_OK) {
|
||||
if (fno.fattrib & AM_DIR) {
|
||||
// exists as a directory
|
||||
// TODO handle this case
|
||||
// see http://elm-chan.org/fsw/ff/img/app2.c for a "rm -rf" implementation
|
||||
} else {
|
||||
// exists as a file, good!
|
||||
}
|
||||
} else {
|
||||
// doesn't exist, create fresh file
|
||||
|
||||
// LED on to indicate creation of boot.py
|
||||
led_state(PYB_LED_R2, 1);
|
||||
uint32_t stc = sys_tick_counter;
|
||||
|
||||
FIL fp;
|
||||
f_open(&fp, "0:/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
UINT n;
|
||||
f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n);
|
||||
// TODO check we could write n bytes
|
||||
f_close(&fp);
|
||||
|
||||
// keep LED on for at least 200ms
|
||||
sys_tick_wait_at_least(stc, 200);
|
||||
led_state(PYB_LED_R2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// run /boot.py
|
||||
if (!pyexec_file("0:/boot.py")) {
|
||||
flash_error(4);
|
||||
}
|
||||
|
||||
if (first_soft_reset) {
|
||||
#if MICROPY_HW_HAS_MMA7660
|
||||
// MMA accel: init and reset address to zero
|
||||
accel_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
// turn boot-up LED off
|
||||
led_state(PYB_LED_G1, 0);
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
// if an SD card is present then mount it on 1:/
|
||||
if (sdcard_is_present()) {
|
||||
FRESULT res = f_mount(&fatfs1, "1:", 1);
|
||||
if (res != FR_OK) {
|
||||
printf("[SD] could not mount SD card\n");
|
||||
} else {
|
||||
if (first_soft_reset) {
|
||||
// use SD card as medium for the USB MSD
|
||||
usbd_storage_select_medium(USBD_STORAGE_MEDIUM_SDCARD);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_HOST_MODE
|
||||
// USB host
|
||||
pyb_usb_host_init();
|
||||
#elif defined(USE_DEVICE_MODE)
|
||||
// USB device
|
||||
pyb_usb_dev_init(PYB_USB_DEV_VCP_MSC);
|
||||
#endif
|
||||
|
||||
// run main script
|
||||
{
|
||||
vstr_t *vstr = vstr_new();
|
||||
vstr_add_str(vstr, "0:/");
|
||||
if (pyb_config_source_dir == MP_OBJ_NULL) {
|
||||
vstr_add_str(vstr, "src");
|
||||
} else {
|
||||
vstr_add_str(vstr, mp_obj_str_get_str(pyb_config_source_dir));
|
||||
}
|
||||
vstr_add_char(vstr, '/');
|
||||
if (pyb_config_main == MP_OBJ_NULL) {
|
||||
vstr_add_str(vstr, "main.py");
|
||||
} else {
|
||||
vstr_add_str(vstr, mp_obj_str_get_str(pyb_config_main));
|
||||
}
|
||||
if (!pyexec_file(vstr_str(vstr))) {
|
||||
flash_error(3);
|
||||
}
|
||||
vstr_free(vstr);
|
||||
}
|
||||
|
||||
|
||||
#if MICROPY_HW_HAS_MMA7660
|
||||
// HID example
|
||||
if (0) {
|
||||
uint8_t data[4];
|
||||
data[0] = 0;
|
||||
data[1] = 1;
|
||||
data[2] = -2;
|
||||
data[3] = 0;
|
||||
for (;;) {
|
||||
#if MICROPY_HW_HAS_SWITCH
|
||||
if (switch_get()) {
|
||||
data[0] = 0x01; // 0x04 is middle, 0x02 is right
|
||||
} else {
|
||||
data[0] = 0x00;
|
||||
}
|
||||
#else
|
||||
data[0] = 0x00;
|
||||
#endif
|
||||
accel_start(0x4c /* ACCEL_ADDR */, 1);
|
||||
accel_send_byte(0);
|
||||
accel_restart(0x4c /* ACCEL_ADDR */, 0);
|
||||
for (int i = 0; i <= 1; i++) {
|
||||
int v = accel_read_ack() & 0x3f;
|
||||
if (v & 0x20) {
|
||||
v |= ~0x1f;
|
||||
}
|
||||
data[1 + i] = v;
|
||||
}
|
||||
accel_read_nack();
|
||||
usb_hid_send_report(data);
|
||||
sys_tick_delay_ms(15);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_HAS_WLAN
|
||||
// wifi
|
||||
pyb_wlan_init();
|
||||
pyb_wlan_start();
|
||||
#endif
|
||||
|
||||
pyexec_repl();
|
||||
|
||||
printf("PYB: sync filesystems\n");
|
||||
storage_flush();
|
||||
|
||||
printf("PYB: soft reboot\n");
|
||||
|
||||
first_soft_reset = false;
|
||||
goto soft_reset;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "gc.h"
|
||||
|
||||
#if 0
|
||||
static uint32_t mem = 0;
|
||||
|
||||
void *malloc(size_t n) {
|
||||
if (mem == 0) {
|
||||
extern uint32_t _heap_start;
|
||||
mem = (uint32_t)&_heap_start; // need to use big ram block so we can execute code from it (is it true that we can't execute from CCM?)
|
||||
}
|
||||
void *ptr = (void*)mem;
|
||||
mem = (mem + n + 3) & (~3);
|
||||
if (mem > 0x20000000 + 0x18000) {
|
||||
void __fatal_error(const char*);
|
||||
__fatal_error("out of memory");
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void free(void *ptr) {
|
||||
}
|
||||
|
||||
void *realloc(void *ptr, size_t n) {
|
||||
return malloc(n);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void __assert_func(void) {
|
||||
printf("\nASSERT FAIL!");
|
||||
for (;;) {
|
||||
}
|
||||
}
|
454
stm/math.c
454
stm/math.c
@ -1,454 +0,0 @@
|
||||
#include <stdint.h>
|
||||
typedef float float_t;
|
||||
typedef union {
|
||||
float f;
|
||||
struct {
|
||||
uint64_t m : 23;
|
||||
uint64_t e : 8;
|
||||
uint64_t s : 1;
|
||||
};
|
||||
} float_s_t;
|
||||
|
||||
typedef union {
|
||||
double d;
|
||||
struct {
|
||||
uint64_t m : 52;
|
||||
uint64_t e : 11;
|
||||
uint64_t s : 1;
|
||||
};
|
||||
} double_s_t;
|
||||
|
||||
double __attribute__((pcs("aapcs"))) __aeabi_i2d(int32_t x) {
|
||||
return (float)x;
|
||||
}
|
||||
|
||||
double __attribute__((pcs("aapcs"))) __aeabi_f2d(float x) {
|
||||
float_s_t fx={0};
|
||||
double_s_t dx={0};
|
||||
|
||||
fx.f = x;
|
||||
dx.s = (fx.s);
|
||||
dx.e = (fx.e-127+1023) & 0x7FF;
|
||||
dx.m = fx.m;
|
||||
dx.m <<=(52-23); // left justify
|
||||
return dx.d;
|
||||
}
|
||||
|
||||
float __attribute__((pcs("aapcs"))) __aeabi_d2f(double x) {
|
||||
float_s_t fx={0};
|
||||
double_s_t dx={0};
|
||||
|
||||
dx.d = x;
|
||||
fx.s = (dx.s);
|
||||
fx.e = (dx.e-1023+127) & 0xFF;
|
||||
fx.m = (dx.m>>(52-23)); // right justify
|
||||
return fx.f;
|
||||
}
|
||||
double __aeabi_dmul(double x , double y) {
|
||||
return 0.0;
|
||||
|
||||
}
|
||||
/*
|
||||
double sqrt(double x) {
|
||||
// TODO
|
||||
return 0.0;
|
||||
}
|
||||
*/
|
||||
|
||||
float sqrtf(float x) {
|
||||
asm volatile (
|
||||
"vsqrt.f32 %[r], %[x]\n"
|
||||
: [r] "=t" (x)
|
||||
: [x] "t" (x));
|
||||
return x;
|
||||
}
|
||||
|
||||
// TODO we need import these functions from some library (eg musl or newlib)
|
||||
float powf(float x, float y) { return 0.0; }
|
||||
float logf(float x) { return 0.0; }
|
||||
float log2f(float x) { return 0.0; }
|
||||
float log10f(float x) { return 0.0; }
|
||||
float tanhf(float x) { return 0.0; }
|
||||
float acoshf(float x) { return 0.0; }
|
||||
float asinhf(float x) { return 0.0; }
|
||||
float atanhf(float x) { return 0.0; }
|
||||
float cosf(float x) { return 0.0; }
|
||||
float sinf(float x) { return 0.0; }
|
||||
float tanf(float x) { return 0.0; }
|
||||
float acosf(float x) { return 0.0; }
|
||||
float asinf(float x) { return 0.0; }
|
||||
float atanf(float x) { return 0.0; }
|
||||
float atan2f(float x, float y) { return 0.0; }
|
||||
float ceilf(float x) { return 0.0; }
|
||||
float floorf(float x) { return 0.0; }
|
||||
float truncf(float x) { return 0.0; }
|
||||
float fmodf(float x, float y) { return 0.0; }
|
||||
float tgammaf(float x) { return 0.0; }
|
||||
float lgammaf(float x) { return 0.0; }
|
||||
float erff(float x) { return 0.0; }
|
||||
float erfcf(float x) { return 0.0; }
|
||||
float modff(float x, float *y) { return 0.0; }
|
||||
float frexpf(float x, int *exp) { return 0.0; }
|
||||
float ldexpf(float x, int exp) { return 0.0; }
|
||||
int __fpclassifyf(float x) { return 0; }
|
||||
|
||||
/*****************************************************************************/
|
||||
// from musl-0.9.15 libm.h
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#define FORCE_EVAL(x) do { \
|
||||
if (sizeof(x) == sizeof(float)) { \
|
||||
volatile float __x; \
|
||||
__x = (x); \
|
||||
(void)__x; \
|
||||
} else if (sizeof(x) == sizeof(double)) { \
|
||||
volatile double __x; \
|
||||
__x = (x); \
|
||||
(void)__x; \
|
||||
} else { \
|
||||
volatile long double __x; \
|
||||
__x = (x); \
|
||||
(void)__x; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Get a 32 bit int from a float. */
|
||||
#define GET_FLOAT_WORD(w,d) \
|
||||
do { \
|
||||
union {float f; uint32_t i;} __u; \
|
||||
__u.f = (d); \
|
||||
(w) = __u.i; \
|
||||
} while (0)
|
||||
|
||||
/* Set a float from a 32 bit int. */
|
||||
#define SET_FLOAT_WORD(d,w) \
|
||||
do { \
|
||||
union {float f; uint32_t i;} __u; \
|
||||
__u.i = (w); \
|
||||
(d) = __u.f; \
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************/
|
||||
// scalbnf from musl-0.9.15
|
||||
|
||||
float scalbnf(float x, int n)
|
||||
{
|
||||
union {float f; uint32_t i;} u;
|
||||
float_t y = x;
|
||||
|
||||
if (n > 127) {
|
||||
y *= 0x1p127f;
|
||||
n -= 127;
|
||||
if (n > 127) {
|
||||
y *= 0x1p127f;
|
||||
n -= 127;
|
||||
if (n > 127)
|
||||
n = 127;
|
||||
}
|
||||
} else if (n < -126) {
|
||||
y *= 0x1p-126f;
|
||||
n += 126;
|
||||
if (n < -126) {
|
||||
y *= 0x1p-126f;
|
||||
n += 126;
|
||||
if (n < -126)
|
||||
n = -126;
|
||||
}
|
||||
}
|
||||
u.i = (uint32_t)(0x7f+n)<<23;
|
||||
x = y * u.f;
|
||||
return x;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// expf from musl-0.9.15
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/e_expf.c */
|
||||
/*
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
static const float
|
||||
half[2] = {0.5,-0.5},
|
||||
ln2hi = 6.9314575195e-1f, /* 0x3f317200 */
|
||||
ln2lo = 1.4286067653e-6f, /* 0x35bfbe8e */
|
||||
invln2 = 1.4426950216e+0f, /* 0x3fb8aa3b */
|
||||
/*
|
||||
* Domain [-0.34568, 0.34568], range ~[-4.278e-9, 4.447e-9]:
|
||||
* |x*(exp(x)+1)/(exp(x)-1) - p(x)| < 2**-27.74
|
||||
*/
|
||||
P1 = 1.6666625440e-1f, /* 0xaaaa8f.0p-26 */
|
||||
P2 = -2.7667332906e-3f; /* -0xb55215.0p-32 */
|
||||
|
||||
float expf(float x)
|
||||
{
|
||||
float_t hi, lo, c, xx, y;
|
||||
int k, sign;
|
||||
uint32_t hx;
|
||||
|
||||
GET_FLOAT_WORD(hx, x);
|
||||
sign = hx >> 31; /* sign bit of x */
|
||||
hx &= 0x7fffffff; /* high word of |x| */
|
||||
|
||||
/* special cases */
|
||||
if (hx >= 0x42aeac50) { /* if |x| >= -87.33655f or NaN */
|
||||
if (hx >= 0x42b17218 && !sign) { /* x >= 88.722839f */
|
||||
/* overflow */
|
||||
x *= 0x1p127f;
|
||||
return x;
|
||||
}
|
||||
if (sign) {
|
||||
/* underflow */
|
||||
FORCE_EVAL(-0x1p-149f/x);
|
||||
if (hx >= 0x42cff1b5) /* x <= -103.972084f */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* argument reduction */
|
||||
if (hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
|
||||
if (hx > 0x3f851592) /* if |x| > 1.5 ln2 */
|
||||
k = invln2*x + half[sign];
|
||||
else
|
||||
k = 1 - sign - sign;
|
||||
hi = x - k*ln2hi; /* k*ln2hi is exact here */
|
||||
lo = k*ln2lo;
|
||||
x = hi - lo;
|
||||
} else if (hx > 0x39000000) { /* |x| > 2**-14 */
|
||||
k = 0;
|
||||
hi = x;
|
||||
lo = 0;
|
||||
} else {
|
||||
/* raise inexact */
|
||||
FORCE_EVAL(0x1p127f + x);
|
||||
return 1 + x;
|
||||
}
|
||||
|
||||
/* x is now in primary range */
|
||||
xx = x*x;
|
||||
c = x - xx*(P1+xx*P2);
|
||||
y = 1 + (x*c/(2-c) - lo + hi);
|
||||
if (k == 0)
|
||||
return y;
|
||||
return scalbnf(y, k);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// expm1f from musl-0.9.15
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1f.c */
|
||||
/*
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
static const float
|
||||
o_threshold = 8.8721679688e+01, /* 0x42b17180 */
|
||||
ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
|
||||
ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
|
||||
//invln2 = 1.4426950216e+00, /* 0x3fb8aa3b */
|
||||
/*
|
||||
* Domain [-0.34568, 0.34568], range ~[-6.694e-10, 6.696e-10]:
|
||||
* |6 / x * (1 + 2 * (1 / (exp(x) - 1) - 1 / x)) - q(x)| < 2**-30.04
|
||||
* Scaled coefficients: Qn_here = 2**n * Qn_for_q (see s_expm1.c):
|
||||
*/
|
||||
Q1 = -3.3333212137e-2, /* -0x888868.0p-28 */
|
||||
Q2 = 1.5807170421e-3; /* 0xcf3010.0p-33 */
|
||||
|
||||
float expm1f(float x)
|
||||
{
|
||||
float_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk;
|
||||
union {float f; uint32_t i;} u = {x};
|
||||
uint32_t hx = u.i & 0x7fffffff;
|
||||
int k, sign = u.i >> 31;
|
||||
|
||||
/* filter out huge and non-finite argument */
|
||||
if (hx >= 0x4195b844) { /* if |x|>=27*ln2 */
|
||||
if (hx > 0x7f800000) /* NaN */
|
||||
return x;
|
||||
if (sign)
|
||||
return -1;
|
||||
if (x > o_threshold) {
|
||||
x *= 0x1p127f;
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* argument reduction */
|
||||
if (hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
|
||||
if (hx < 0x3F851592) { /* and |x| < 1.5 ln2 */
|
||||
if (!sign) {
|
||||
hi = x - ln2_hi;
|
||||
lo = ln2_lo;
|
||||
k = 1;
|
||||
} else {
|
||||
hi = x + ln2_hi;
|
||||
lo = -ln2_lo;
|
||||
k = -1;
|
||||
}
|
||||
} else {
|
||||
k = invln2*x + (sign ? -0.5f : 0.5f);
|
||||
t = k;
|
||||
hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
|
||||
lo = t*ln2_lo;
|
||||
}
|
||||
x = hi-lo;
|
||||
c = (hi-x)-lo;
|
||||
} else if (hx < 0x33000000) { /* when |x|<2**-25, return x */
|
||||
if (hx < 0x00800000)
|
||||
FORCE_EVAL(x*x);
|
||||
return x;
|
||||
} else
|
||||
k = 0;
|
||||
|
||||
/* x is now in primary range */
|
||||
hfx = 0.5f*x;
|
||||
hxs = x*hfx;
|
||||
r1 = 1.0f+hxs*(Q1+hxs*Q2);
|
||||
t = 3.0f - r1*hfx;
|
||||
e = hxs*((r1-t)/(6.0f - x*t));
|
||||
if (k == 0) /* c is 0 */
|
||||
return x - (x*e-hxs);
|
||||
e = x*(e-c) - c;
|
||||
e -= hxs;
|
||||
/* exp(x) ~ 2^k (x_reduced - e + 1) */
|
||||
if (k == -1)
|
||||
return 0.5f*(x-e) - 0.5f;
|
||||
if (k == 1) {
|
||||
if (x < -0.25f)
|
||||
return -2.0f*(e-(x+0.5f));
|
||||
return 1.0f + 2.0f*(x-e);
|
||||
}
|
||||
u.i = (0x7f+k)<<23; /* 2^k */
|
||||
twopk = u.f;
|
||||
if (k < 0 || k > 56) { /* suffice to return exp(x)-1 */
|
||||
y = x - e + 1.0f;
|
||||
if (k == 128)
|
||||
y = y*2.0f*0x1p127f;
|
||||
else
|
||||
y = y*twopk;
|
||||
return y - 1.0f;
|
||||
}
|
||||
u.i = (0x7f-k)<<23; /* 2^-k */
|
||||
if (k < 23)
|
||||
y = (x-e+(1-u.f))*twopk;
|
||||
else
|
||||
y = (x-(e+u.f)+1)*twopk;
|
||||
return y;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// __expo2f from musl-0.9.15
|
||||
|
||||
/* k is such that k*ln2 has minimal relative error and x - kln2 > log(FLT_MIN) */
|
||||
static const int k = 235;
|
||||
static const float kln2 = 0x1.45c778p+7f;
|
||||
|
||||
/* expf(x)/2 for x >= log(FLT_MAX), slightly better than 0.5f*expf(x/2)*expf(x/2) */
|
||||
float __expo2f(float x)
|
||||
{
|
||||
float scale;
|
||||
|
||||
/* note that k is odd and scale*scale overflows */
|
||||
SET_FLOAT_WORD(scale, (uint32_t)(0x7f + k/2) << 23);
|
||||
/* exp(x - k ln2) * 2**(k-1) */
|
||||
return expf(x - kln2) * scale * scale;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// coshf from musl-0.9.15
|
||||
|
||||
float coshf(float x)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {.f = x};
|
||||
uint32_t w;
|
||||
float t;
|
||||
|
||||
/* |x| */
|
||||
u.i &= 0x7fffffff;
|
||||
x = u.f;
|
||||
w = u.i;
|
||||
|
||||
/* |x| < log(2) */
|
||||
if (w < 0x3f317217) {
|
||||
if (w < 0x3f800000 - (12<<23)) {
|
||||
FORCE_EVAL(x + 0x1p120f);
|
||||
return 1;
|
||||
}
|
||||
t = expm1f(x);
|
||||
return 1 + t*t/(2*(1+t));
|
||||
}
|
||||
|
||||
/* |x| < log(FLT_MAX) */
|
||||
if (w < 0x42b17217) {
|
||||
t = expf(x);
|
||||
return 0.5f*(t + 1/t);
|
||||
}
|
||||
|
||||
/* |x| > log(FLT_MAX) or nan */
|
||||
t = __expo2f(x);
|
||||
return t;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// sinhf from musl-0.9.15
|
||||
|
||||
float sinhf(float x)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {.f = x};
|
||||
uint32_t w;
|
||||
float t, h, absx;
|
||||
|
||||
h = 0.5;
|
||||
if (u.i >> 31)
|
||||
h = -h;
|
||||
/* |x| */
|
||||
u.i &= 0x7fffffff;
|
||||
absx = u.f;
|
||||
w = u.i;
|
||||
|
||||
/* |x| < log(FLT_MAX) */
|
||||
if (w < 0x42b17217) {
|
||||
t = expm1f(absx);
|
||||
if (w < 0x3f800000) {
|
||||
if (w < 0x3f800000 - (12<<23))
|
||||
return x;
|
||||
return h*(2*t - t*t/(t+1));
|
||||
}
|
||||
return h*(t + t/(t+1));
|
||||
}
|
||||
|
||||
/* |x| > logf(FLT_MAX) or nan */
|
||||
t = 2*h*__expo2f(absx);
|
||||
return t;
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
#include <stdint.h>
|
||||
|
||||
// options to control how Micro Python is built
|
||||
|
||||
#define MICROPY_EMIT_THUMB (1)
|
||||
#define MICROPY_EMIT_INLINE_THUMB (1)
|
||||
#define MICROPY_ENABLE_GC (1)
|
||||
#define MICROPY_ENABLE_FINALISER (1)
|
||||
#define MICROPY_ENABLE_REPL_HELPERS (1)
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
|
||||
#define MICROPY_PATH_MAX (128)
|
||||
/* Enable FatFS LFNs
|
||||
0: Disable LFN feature.
|
||||
1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
|
||||
2: Enable LFN with dynamic working buffer on the STACK.
|
||||
3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
*/
|
||||
#define MICROPY_ENABLE_LFN (0)
|
||||
#define MICROPY_LFN_CODE_PAGE (1) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
|
||||
|
||||
extern const struct _mp_obj_fun_native_t mp_builtin_open_obj;
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
#define BYTES_PER_WORD (4)
|
||||
|
||||
#define UINT_FMT "%lu"
|
||||
#define INT_FMT "%ld"
|
||||
|
||||
typedef int32_t machine_int_t; // must be pointer size
|
||||
typedef uint32_t machine_uint_t; // must be pointer size
|
||||
typedef void *machine_ptr_t; // must be of pointer size
|
||||
typedef const void *machine_const_ptr_t; // must be of pointer size
|
||||
|
||||
// There is no classical C heap in bare-metal ports, only Python
|
||||
// garbage-collected heap. For completeness, emulate C heap via
|
||||
// GC heap. Note that MicroPython core never uses malloc() and friends,
|
||||
// so these defines are mostly to help extension module writers.
|
||||
#define malloc gc_alloc
|
||||
#define free gc_free
|
||||
#define realloc gc_realloc
|
||||
|
||||
// board specific definitions
|
||||
|
||||
#include "mpconfigboard.h"
|
||||
|
||||
#define STM32F40_41xxx
|
||||
#define USE_STDPERIPH_DRIVER
|
||||
#if !defined(HSE_VALUE)
|
||||
#define HSE_VALUE (8000000)
|
||||
#endif
|
||||
#define USE_DEVICE_MODE
|
||||
//#define USE_HOST_MODE
|
83
stm/pendsv.c
83
stm/pendsv.c
@ -1,83 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stm32f4xx.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "pendsv.h"
|
||||
|
||||
static mp_obj_t pendsv_object = MP_OBJ_NULL;
|
||||
|
||||
void pendsv_init(void) {
|
||||
// set PendSV interrupt at lowest priority
|
||||
NVIC_SetPriority(PendSV_IRQn, 0xff);
|
||||
}
|
||||
|
||||
// call this function to raise a pending exception during an interrupt
|
||||
// it will wait until all interrupts are finished then raise the given
|
||||
// exception object using nlr_jump in the context of the top-level thread
|
||||
void pendsv_nlr_jump(mp_obj_t o) {
|
||||
pendsv_object = o;
|
||||
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
|
||||
}
|
||||
|
||||
// since we play tricks with the stack, the compiler must not generate a
|
||||
// prelude for this function
|
||||
void pendsv_isr_handler(void) __attribute__((naked));
|
||||
|
||||
void pendsv_isr_handler(void) {
|
||||
// re-jig the stack so that when we return from this interrupt handler
|
||||
// it returns instead to nlr_jump with argument pendsv_object
|
||||
// note that stack has a different layout if DEBUG is enabled
|
||||
//
|
||||
// on entry to this (naked) function, stack has the following layout:
|
||||
//
|
||||
// stack layout with DEBUG disabled:
|
||||
// sp[6]: pc
|
||||
// sp[5]: ?
|
||||
// sp[4]: ?
|
||||
// sp[3]: ?
|
||||
// sp[2]: ?
|
||||
// sp[1]: ?
|
||||
// sp[0]: r0
|
||||
//
|
||||
// stack layout with DEBUG enabled:
|
||||
// sp[8]: pc
|
||||
// sp[7]: lr
|
||||
// sp[6]: ?
|
||||
// sp[5]: ?
|
||||
// sp[4]: ?
|
||||
// sp[3]: ?
|
||||
// sp[2]: r0
|
||||
// sp[1]: 0xfffffff9
|
||||
// sp[0]: ?
|
||||
|
||||
__asm volatile (
|
||||
"ldr r0, pendsv_object_ptr\n"
|
||||
"ldr r0, [r0]\n"
|
||||
#if defined(PENDSV_DEBUG)
|
||||
"str r0, [sp, #8]\n"
|
||||
#else
|
||||
"str r0, [sp, #0]\n"
|
||||
#endif
|
||||
"ldr r0, nlr_jump_ptr\n"
|
||||
#if defined(PENDSV_DEBUG)
|
||||
"str r0, [sp, #32]\n"
|
||||
#else
|
||||
"str r0, [sp, #24]\n"
|
||||
#endif
|
||||
"bx lr\n"
|
||||
".align 2\n"
|
||||
"pendsv_object_ptr: .word pendsv_object\n"
|
||||
"nlr_jump_ptr: .word nlr_jump\n"
|
||||
);
|
||||
|
||||
/*
|
||||
uint32_t x[2] = {0x424242, 0xdeaddead};
|
||||
printf("PendSV: %p\n", x);
|
||||
for (uint32_t *p = (uint32_t*)(((uint32_t)x - 15) & 0xfffffff0), i = 64; i > 0; p += 4, i -= 4) {
|
||||
printf(" %p: %08x %08x %08x %08x\n", p, (uint)p[0], (uint)p[1], (uint)p[2], (uint)p[3]);
|
||||
}
|
||||
*/
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
void pendsv_init(void);
|
||||
void pendsv_nlr_jump(mp_obj_t o);
|
||||
void pendsv_isr_handler(void);
|
63
stm/pin.c
63
stm/pin.c
@ -1,63 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stm32f4xx.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
|
||||
#include "pin.h"
|
||||
|
||||
void pin_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pin_obj_t *self = self_in;
|
||||
print(env, "<Pin %s>", self->name);
|
||||
}
|
||||
|
||||
mp_obj_t pin_obj_name(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_QSTR(qstr_from_str(self->name));
|
||||
}
|
||||
|
||||
mp_obj_t pin_obj_port(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_SMALL_INT((mp_small_int_t)self->port);
|
||||
}
|
||||
|
||||
mp_obj_t pin_obj_pin(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_SMALL_INT((mp_small_int_t)self->pin);
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(pin_obj_name_obj, pin_obj_name);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(pin_obj_port_obj, pin_obj_port);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(pin_obj_pin_obj, pin_obj_pin);
|
||||
|
||||
STATIC const mp_map_elem_t pin_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_name), (mp_obj_t)&pin_obj_name_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_port), (mp_obj_t)&pin_obj_port_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pin), (mp_obj_t)&pin_obj_pin_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pin_locals_dict, pin_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pin_obj_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_Pin,
|
||||
.print = pin_obj_print,
|
||||
.locals_dict = (mp_obj_t)&pin_locals_dict,
|
||||
};
|
||||
|
||||
void pin_af_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pin_af_obj_t *self = self_in;
|
||||
print(env, "<Pin AF %d fn:%d unit:%d typ:%d>", self->idx, self->fn,
|
||||
self->unit, self->type);
|
||||
}
|
||||
|
||||
const mp_obj_type_t pin_af_obj_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_PinAF,
|
||||
.print = pin_af_obj_print,
|
||||
};
|
||||
|
117
stm/pin.h
117
stm/pin.h
@ -1,117 +0,0 @@
|
||||
enum {
|
||||
PORT_A,
|
||||
PORT_B,
|
||||
PORT_C,
|
||||
PORT_D,
|
||||
PORT_E,
|
||||
PORT_F,
|
||||
PORT_G,
|
||||
PORT_H,
|
||||
PORT_I,
|
||||
PORT_J,
|
||||
};
|
||||
|
||||
enum {
|
||||
AF_FN_TIM,
|
||||
AF_FN_I2C,
|
||||
AF_FN_USART,
|
||||
AF_FN_UART = AF_FN_USART,
|
||||
AF_FN_SPI
|
||||
};
|
||||
|
||||
enum {
|
||||
AF_PIN_TYPE_TIM_CH1 = 0,
|
||||
AF_PIN_TYPE_TIM_CH2,
|
||||
AF_PIN_TYPE_TIM_CH3,
|
||||
AF_PIN_TYPE_TIM_CH4,
|
||||
AF_PIN_TYPE_TIM_CH1N,
|
||||
AF_PIN_TYPE_TIM_CH2N,
|
||||
AF_PIN_TYPE_TIM_CH3N,
|
||||
AF_PIN_TYPE_TIM_CH1_ETR,
|
||||
AF_PIN_TYPE_TIM_ETR,
|
||||
AF_PIN_TYPE_TIM_BKIN,
|
||||
|
||||
AF_PIN_TYPE_I2C_SDA = 0,
|
||||
AF_PIN_TYPE_I2C_SCL,
|
||||
|
||||
AF_PIN_TYPE_USART_TX = 0,
|
||||
AF_PIN_TYPE_USART_RX,
|
||||
AF_PIN_TYPE_USART_CTS,
|
||||
AF_PIN_TYPE_USART_RTS,
|
||||
AF_PIN_TYPE_USART_CK,
|
||||
AF_PIN_TYPE_UART_TX = AF_PIN_TYPE_USART_TX,
|
||||
AF_PIN_TYPE_UART_RX = AF_PIN_TYPE_USART_RX,
|
||||
AF_PIN_TYPE_UART_CTS = AF_PIN_TYPE_USART_CTS,
|
||||
AF_PIN_TYPE_UART_RTS = AF_PIN_TYPE_USART_RTS,
|
||||
|
||||
AF_PIN_TYPE_SPI_MOSI = 0,
|
||||
AF_PIN_TYPE_SPI_MISO,
|
||||
AF_PIN_TYPE_SPI_SCK,
|
||||
AF_PIN_TYPE_SPI_NSS,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
uint8_t idx;
|
||||
uint8_t fn;
|
||||
uint8_t unit;
|
||||
uint8_t type;
|
||||
|
||||
union {
|
||||
void *reg;
|
||||
TIM_TypeDef *TIM;
|
||||
I2C_TypeDef *I2C;
|
||||
USART_TypeDef *USART;
|
||||
USART_TypeDef *UART;
|
||||
SPI_TypeDef *SPI;
|
||||
};
|
||||
} pin_af_obj_t;
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
const char *name;
|
||||
uint16_t port : 4;
|
||||
uint16_t pin : 4;
|
||||
uint16_t num_af : 4;
|
||||
uint16_t pin_mask;
|
||||
GPIO_TypeDef *gpio;
|
||||
const pin_af_obj_t *af;
|
||||
} pin_obj_t;
|
||||
|
||||
extern const mp_obj_type_t pin_obj_type;
|
||||
extern const mp_obj_type_t pin_af_obj_type;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const pin_obj_t *pin;
|
||||
} pin_named_pin_t;
|
||||
|
||||
extern const pin_named_pin_t pin_board_pins[];
|
||||
extern const pin_named_pin_t pin_cpu_pins[];
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t mapper;
|
||||
mp_obj_t map_dict;
|
||||
bool debug;
|
||||
} pin_map_obj_t;
|
||||
|
||||
extern pin_map_obj_t pin_map_obj;
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
const char *name;
|
||||
const pin_named_pin_t *named_pins;
|
||||
} pin_named_pins_obj_t;
|
||||
|
||||
extern const pin_named_pins_obj_t pin_board_pins_obj;
|
||||
extern const pin_named_pins_obj_t pin_cpu_pins_obj;
|
||||
|
||||
const pin_obj_t *pin_find_named_pin(const pin_named_pin_t *pins, const char *name);
|
||||
const pin_af_obj_t *pin_find_af(const pin_obj_t *pin, uint8_t fn, uint8_t unit, uint8_t pin_type);
|
||||
|
||||
void pin_map_init(void);
|
||||
|
||||
// C function for mapping python pin identifier into an ordinal pin number.
|
||||
const pin_obj_t *pin_map_user_obj(mp_obj_t user_obj);
|
||||
|
226
stm/pin_map.c
226
stm/pin_map.c
@ -1,226 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stm32f4xx.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "nlr.h"
|
||||
|
||||
#include "pin.h"
|
||||
|
||||
// Usage Model:
|
||||
//
|
||||
// All Board Pins are predefined as pyb.Pin.board.Name
|
||||
//
|
||||
// x1_pin = pyb.Pin.board.X1
|
||||
//
|
||||
// g = pyb.gpio(pyb.Pin.board.X1, 0)
|
||||
//
|
||||
// CPU pins which correspond to the board pins are available
|
||||
// as pyb.cpu.Name. For the CPU pins, the names are the port letter
|
||||
// followed by the pin number. On the PYBOARD4, pyb.Pin.board.X1 and
|
||||
// pyb.Pin.cpu.B6 are the same pin.
|
||||
//
|
||||
// You can also use strings:
|
||||
//
|
||||
// g = pyb.gpio('X1', 0)
|
||||
//
|
||||
// Users can add their own names:
|
||||
//
|
||||
// pyb.Pin("LeftMotorDir", pyb.Pin.cpu.C12)
|
||||
// g = pyb.gpio("LeftMotorDir", 0)
|
||||
//
|
||||
// and can query mappings
|
||||
//
|
||||
// pin = pyb.Pin("LeftMotorDir");
|
||||
//
|
||||
// Users can also add their own mapping function:
|
||||
//
|
||||
// def MyMapper(pin_name):
|
||||
// if pin_name == "LeftMotorDir":
|
||||
// return pyb.Pin.cpu.A0
|
||||
//
|
||||
// pyb.Pin.mapper(MyMapper)
|
||||
//
|
||||
// So, if you were to call: pyb.gpio("LeftMotorDir", 0)
|
||||
// then "LeftMotorDir" is passed directly to the mapper function.
|
||||
//
|
||||
// To summarize, the following order determines how things get mapped into
|
||||
// an ordinal pin number:
|
||||
//
|
||||
// 1 - Directly specify a pin object
|
||||
// 2 - User supplied mapping function
|
||||
// 3 - User supplied mapping (object must be usable as a dictionary key)
|
||||
// 4 - Supply a string which matches a board pin
|
||||
// 5 - Supply a string which matches a CPU port/pin
|
||||
//
|
||||
// You can set pyb.Pin.debug(True) to get some debug information about
|
||||
// how a particular object gets mapped to a pin.
|
||||
|
||||
static void pin_map_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)self_in;
|
||||
print(env, "<PinMap>");
|
||||
}
|
||||
|
||||
static mp_obj_t pin_map_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
|
||||
pin_map_obj_t *self = self_in;
|
||||
mp_arg_check_num(n_args, n_kw, 1, 2, false);
|
||||
|
||||
if (n_args > 1) {
|
||||
if (!self->map_dict) {
|
||||
self->map_dict = mp_obj_new_dict(1);
|
||||
}
|
||||
mp_obj_dict_store(self->map_dict, args[0], args[1]);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
// Run an argument through the mapper and return the result.
|
||||
return (mp_obj_t)pin_map_user_obj(args[0]);
|
||||
}
|
||||
|
||||
static mp_obj_t pin_map_obj_mapper(uint n_args, mp_obj_t *args) {
|
||||
pin_map_obj_t *self = args[0];
|
||||
if (n_args > 1) {
|
||||
self->mapper = args[1];
|
||||
return mp_const_none;
|
||||
}
|
||||
return self->mapper;
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_map_obj_mapper_obj, 1, 2, pin_map_obj_mapper);
|
||||
|
||||
static mp_obj_t pin_map_obj_debug(uint n_args, mp_obj_t *args) {
|
||||
pin_map_obj_t *self = args[0];
|
||||
if (n_args > 1) {
|
||||
self->debug = mp_obj_is_true(args[1]);
|
||||
return mp_const_none;
|
||||
}
|
||||
return MP_BOOL(self->debug);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_map_obj_debug_obj, 1, 2, pin_map_obj_debug);
|
||||
|
||||
static void pin_map_load_attr(mp_obj_t self_in, qstr attr_qstr, mp_obj_t *dest) {
|
||||
(void)self_in;
|
||||
const char *attr = qstr_str(attr_qstr);
|
||||
|
||||
if (strcmp(attr, "mapper") == 0) {
|
||||
dest[0] = (mp_obj_t)&pin_map_obj_mapper_obj;
|
||||
dest[1] = self_in;
|
||||
}
|
||||
if (strcmp(attr, "debug") == 0) {
|
||||
dest[0] = (mp_obj_t)&pin_map_obj_debug_obj;
|
||||
dest[1] = self_in;
|
||||
}
|
||||
if (strcmp(attr, pin_board_pins_obj.name) == 0) {
|
||||
dest[0] = (mp_obj_t)&pin_board_pins_obj;
|
||||
dest[1] = MP_OBJ_NULL;
|
||||
}
|
||||
if (strcmp(attr, pin_cpu_pins_obj.name) == 0) {
|
||||
dest[0] = (mp_obj_t)&pin_cpu_pins_obj;
|
||||
dest[1] = MP_OBJ_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const mp_obj_type_t pin_map_obj_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_PinMap,
|
||||
.print = pin_map_obj_print,
|
||||
.call = pin_map_call,
|
||||
.load_attr = pin_map_load_attr,
|
||||
};
|
||||
|
||||
static const pin_map_obj_t pin_map_obj_init = {
|
||||
{ &pin_map_obj_type },
|
||||
.mapper = MP_OBJ_NULL,
|
||||
.map_dict = MP_OBJ_NULL,
|
||||
.debug = false,
|
||||
};
|
||||
|
||||
pin_map_obj_t pin_map_obj;
|
||||
|
||||
void pin_map_init(void) {
|
||||
pin_map_obj = pin_map_obj_init;
|
||||
}
|
||||
|
||||
// C API used to convert a user-supplied pin name into an ordinal pin number.
|
||||
const pin_obj_t *pin_map_user_obj(mp_obj_t user_obj) {
|
||||
const pin_obj_t *pin_obj;
|
||||
|
||||
// If a pin was provided, then use it
|
||||
if (MP_OBJ_IS_TYPE(user_obj, &pin_obj_type)) {
|
||||
pin_obj = user_obj;
|
||||
if (pin_map_obj.debug) {
|
||||
printf("Pin map passed pin ");
|
||||
mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
|
||||
printf("\n");
|
||||
}
|
||||
return pin_obj;
|
||||
}
|
||||
|
||||
if (pin_map_obj.mapper) {
|
||||
pin_obj = mp_call_function_1(pin_map_obj.mapper, user_obj);
|
||||
if (pin_obj != mp_const_none) {
|
||||
if (!MP_OBJ_IS_TYPE(pin_obj, &pin_obj_type)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Pin.mapper didn't return a Pin object"));
|
||||
}
|
||||
if (pin_map_obj.debug) {
|
||||
printf("Pin.mapper maps ");
|
||||
mp_obj_print(user_obj, PRINT_REPR);
|
||||
printf(" to ");
|
||||
mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
|
||||
printf("\n");
|
||||
}
|
||||
return pin_obj;
|
||||
}
|
||||
// The pin mapping function returned mp_const_none, fall through to
|
||||
// other lookup methods.
|
||||
}
|
||||
|
||||
if (pin_map_obj.map_dict) {
|
||||
mp_map_t *pin_map_map = mp_obj_dict_get_map(pin_map_obj.map_dict);
|
||||
mp_map_elem_t *elem = mp_map_lookup(pin_map_map, user_obj, MP_MAP_LOOKUP);
|
||||
if (elem != NULL && elem->value != NULL) {
|
||||
pin_obj = elem->value;
|
||||
if (pin_map_obj.debug) {
|
||||
printf("Pin.map_dict maps ");
|
||||
mp_obj_print(user_obj, PRINT_REPR);
|
||||
printf(" to ");
|
||||
mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
|
||||
printf("\n");
|
||||
}
|
||||
return pin_obj;
|
||||
}
|
||||
}
|
||||
|
||||
// See if the pin name matches a board pin
|
||||
const char *pin_name = mp_obj_str_get_str(user_obj);
|
||||
pin_obj = pin_find_named_pin(pin_board_pins, pin_name);
|
||||
if (pin_obj) {
|
||||
if (pin_map_obj.debug) {
|
||||
printf("Pin.board maps ");
|
||||
mp_obj_print(user_obj, PRINT_REPR);
|
||||
printf(" to ");
|
||||
mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
|
||||
printf("\n");
|
||||
}
|
||||
return pin_obj;
|
||||
}
|
||||
|
||||
// See if the pin name matches a cpu pin
|
||||
pin_obj = pin_find_named_pin(pin_cpu_pins, pin_name);
|
||||
if (pin_obj) {
|
||||
if (pin_map_obj.debug) {
|
||||
printf("Pin.cpu maps ");
|
||||
mp_obj_print(user_obj, PRINT_REPR);
|
||||
printf(" to ");
|
||||
mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
|
||||
printf("\n");
|
||||
}
|
||||
return pin_obj;
|
||||
}
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin '%s' not a valid pin identifier", pin_name));
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stm32f4xx.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
#include "pin.h"
|
||||
|
||||
static void pin_named_pins_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pin_named_pins_obj_t *self = self_in;
|
||||
print(env, "<Pin.%s>", self->name);
|
||||
}
|
||||
|
||||
static void pin_named_pins_obj_load_attr(mp_obj_t self_in, qstr attr_qstr, mp_obj_t *dest) {
|
||||
pin_named_pins_obj_t *self = self_in;
|
||||
const char *attr = qstr_str(attr_qstr);
|
||||
const pin_obj_t *pin = pin_find_named_pin(self->named_pins, attr);
|
||||
if (pin) {
|
||||
dest[0] = (mp_obj_t)pin;
|
||||
dest[1] = MP_OBJ_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const mp_obj_type_t pin_named_pins_obj_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_PinNamed,
|
||||
.print = pin_named_pins_obj_print,
|
||||
.load_attr = pin_named_pins_obj_load_attr,
|
||||
};
|
||||
|
||||
const pin_named_pins_obj_t pin_board_pins_obj = {
|
||||
{ &pin_named_pins_obj_type },
|
||||
.name = "board",
|
||||
.named_pins = pin_board_pins,
|
||||
};
|
||||
|
||||
const pin_named_pins_obj_t pin_cpu_pins_obj = {
|
||||
{ &pin_named_pins_obj_type },
|
||||
.name = "cpu",
|
||||
.named_pins = pin_cpu_pins,
|
||||
};
|
||||
|
||||
const pin_obj_t *pin_find_named_pin(const pin_named_pin_t *named_pins, const char *name) {
|
||||
const pin_named_pin_t *named_pin = named_pins;
|
||||
while (named_pin->name) {
|
||||
if (!strcmp(name, named_pin->name)) {
|
||||
return named_pin->pin;
|
||||
}
|
||||
named_pin++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const pin_af_obj_t *pin_find_af(const pin_obj_t *pin, uint8_t fn, uint8_t unit, uint8_t type) {
|
||||
const pin_af_obj_t *af = pin->af;
|
||||
for (int i = 0; i < pin->num_af; i++, af++) {
|
||||
if (af->fn == fn && af->unit == unit && af->type == type) {
|
||||
return af;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
363
stm/printf.c
363
stm/printf.c
@ -1,363 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "std.h"
|
||||
#include "misc.h"
|
||||
#include "systick.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "lcd.h"
|
||||
#include "usart.h"
|
||||
#include "usb.h"
|
||||
|
||||
#if MICROPY_ENABLE_FLOAT
|
||||
#include "formatfloat.h"
|
||||
#endif
|
||||
|
||||
#define PF_FLAG_LEFT_ADJUST (0x01)
|
||||
#define PF_FLAG_SHOW_SIGN (0x02)
|
||||
#define PF_FLAG_SPACE_SIGN (0x04)
|
||||
#define PF_FLAG_NO_TRAILZ (0x08)
|
||||
#define PF_FLAG_ZERO_PAD (0x10)
|
||||
|
||||
// tricky; we compute pad string by: pad_chars + (flags & PF_FLAG_ZERO_PAD)
|
||||
#define PF_PAD_SIZE PF_FLAG_ZERO_PAD
|
||||
static const char *pad_chars = " 0000000000000000";
|
||||
|
||||
typedef struct _pfenv_t {
|
||||
void *data;
|
||||
void (*print_strn)(void *, const char *str, unsigned int len);
|
||||
} pfenv_t;
|
||||
|
||||
static void print_str_dummy(void *data, const char *str, unsigned int len) {
|
||||
}
|
||||
|
||||
const pfenv_t pfenv_dummy = {0, print_str_dummy};
|
||||
|
||||
static int pfenv_print_strn(const pfenv_t *pfenv, const char *str, unsigned int len, int flags, int width) {
|
||||
int pad = width - len;
|
||||
if (pad > 0 && (flags & PF_FLAG_LEFT_ADJUST) == 0) {
|
||||
while (pad > 0) {
|
||||
int p = pad;
|
||||
if (p > PF_PAD_SIZE)
|
||||
p = PF_PAD_SIZE;
|
||||
pfenv->print_strn(pfenv->data, pad_chars + (flags & PF_FLAG_ZERO_PAD), p);
|
||||
pad -= p;
|
||||
}
|
||||
}
|
||||
pfenv->print_strn(pfenv->data, str, len);
|
||||
while (pad > 0) {
|
||||
int p = pad;
|
||||
if (p > PF_PAD_SIZE)
|
||||
p = PF_PAD_SIZE;
|
||||
pfenv->print_strn(pfenv->data, pad_chars, p);
|
||||
pad -= p;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
// enough room for 32 signed number
|
||||
#define INT_BUF_SIZE (12)
|
||||
|
||||
static int pfenv_print_int(const pfenv_t *pfenv, unsigned int x, int sgn, int base, int base_char, int flags, int width) {
|
||||
char sign = 0;
|
||||
if (sgn) {
|
||||
if ((int)x < 0) {
|
||||
sign = '-';
|
||||
x = -x;
|
||||
} else if (flags & PF_FLAG_SHOW_SIGN) {
|
||||
sign = '+';
|
||||
} else if (flags & PF_FLAG_SPACE_SIGN) {
|
||||
sign = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
char buf[INT_BUF_SIZE];
|
||||
char *b = buf + INT_BUF_SIZE;
|
||||
|
||||
if (x == 0) {
|
||||
*(--b) = '0';
|
||||
} else {
|
||||
do {
|
||||
int c = x % base;
|
||||
x /= base;
|
||||
if (c >= 10) {
|
||||
c += base_char - 10;
|
||||
} else {
|
||||
c += '0';
|
||||
}
|
||||
*(--b) = c;
|
||||
} while (b > buf && x != 0);
|
||||
}
|
||||
|
||||
if (b > buf && sign != 0) {
|
||||
*(--b) = sign;
|
||||
}
|
||||
|
||||
return pfenv_print_strn(pfenv, b, buf + INT_BUF_SIZE - b, flags, width);
|
||||
}
|
||||
|
||||
void pfenv_prints(const pfenv_t *pfenv, const char *str) {
|
||||
pfenv->print_strn(pfenv->data, str, strlen(str));
|
||||
}
|
||||
|
||||
int pfenv_printf(const pfenv_t *pfenv, const char *fmt, va_list args) {
|
||||
int chrs = 0;
|
||||
for (;;) {
|
||||
{
|
||||
const char *f = fmt;
|
||||
while (*f != '\0' && *f != '%') {
|
||||
++f; // XXX UTF8 advance char
|
||||
}
|
||||
if (f > fmt) {
|
||||
pfenv->print_strn(pfenv->data, fmt, f - fmt);
|
||||
chrs += f - fmt;
|
||||
fmt = f;
|
||||
}
|
||||
}
|
||||
|
||||
if (*fmt == '\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
// move past % character
|
||||
++fmt;
|
||||
|
||||
// parse flags, if they exist
|
||||
int flags = 0;
|
||||
while (*fmt != '\0') {
|
||||
if (*fmt == '-') flags |= PF_FLAG_LEFT_ADJUST;
|
||||
else if (*fmt == '+') flags |= PF_FLAG_SHOW_SIGN;
|
||||
else if (*fmt == ' ') flags |= PF_FLAG_SPACE_SIGN;
|
||||
else if (*fmt == '!') flags |= PF_FLAG_NO_TRAILZ;
|
||||
else if (*fmt == '0') flags |= PF_FLAG_ZERO_PAD;
|
||||
else break;
|
||||
++fmt;
|
||||
}
|
||||
|
||||
// parse width, if it exists
|
||||
int width = 0;
|
||||
for (; '0' <= *fmt && *fmt <= '9'; ++fmt) {
|
||||
width = width * 10 + *fmt - '0';
|
||||
}
|
||||
|
||||
// parse precision, if it exists
|
||||
int prec = -1;
|
||||
if (*fmt == '.') {
|
||||
++fmt;
|
||||
if (*fmt == '*') {
|
||||
++fmt;
|
||||
prec = va_arg(args, int);
|
||||
} else {
|
||||
prec = 0;
|
||||
for (; '0' <= *fmt && *fmt <= '9'; ++fmt) {
|
||||
prec = prec * 10 + *fmt - '0';
|
||||
}
|
||||
}
|
||||
if (prec < 0) {
|
||||
prec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// parse long specifiers (current not used)
|
||||
//bool long_arg = false;
|
||||
if (*fmt == 'l') {
|
||||
++fmt;
|
||||
//long_arg = true;
|
||||
}
|
||||
|
||||
if (*fmt == '\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (*fmt) {
|
||||
case 'b':
|
||||
if (va_arg(args, int)) {
|
||||
chrs += pfenv_print_strn(pfenv, "true", 4, flags, width);
|
||||
} else {
|
||||
chrs += pfenv_print_strn(pfenv, "false", 5, flags, width);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
{
|
||||
char str = va_arg(args, int);
|
||||
chrs += pfenv_print_strn(pfenv, &str, 1, flags, width);
|
||||
break;
|
||||
}
|
||||
case 's':
|
||||
{
|
||||
const char *str = va_arg(args, const char*);
|
||||
if (str) {
|
||||
if (prec < 0) {
|
||||
prec = strlen(str);
|
||||
}
|
||||
chrs += pfenv_print_strn(pfenv, str, prec, flags, width);
|
||||
} else {
|
||||
chrs += pfenv_print_strn(pfenv, "(null)", 6, flags, width);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
chrs += pfenv_print_int(pfenv, va_arg(args, int), 0, 10, 'a', flags, width);
|
||||
break;
|
||||
case 'd':
|
||||
chrs += pfenv_print_int(pfenv, va_arg(args, int), 1, 10, 'a', flags, width);
|
||||
break;
|
||||
case 'x':
|
||||
case 'p': // ?
|
||||
chrs += pfenv_print_int(pfenv, va_arg(args, int), 0, 16, 'a', flags, width);
|
||||
break;
|
||||
case 'X':
|
||||
case 'P': // ?
|
||||
chrs += pfenv_print_int(pfenv, va_arg(args, int), 0, 16, 'A', flags, width);
|
||||
break;
|
||||
#if MICROPY_ENABLE_FLOAT
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
case 'F':
|
||||
case 'g':
|
||||
case 'G':
|
||||
{
|
||||
char buf[32];
|
||||
char sign = '\0';
|
||||
|
||||
if (flags & PF_FLAG_SHOW_SIGN) {
|
||||
sign = '+';
|
||||
}
|
||||
else
|
||||
if (flags & PF_FLAG_SPACE_SIGN) {
|
||||
sign = ' ';
|
||||
}
|
||||
float f = va_arg(args, double);
|
||||
int len = format_float(f, buf, sizeof(buf), *fmt, prec, sign);
|
||||
char *s = buf;
|
||||
|
||||
// buf[0] < '0' returns true if the first character is space, + or -
|
||||
// buf[1] < '9' matches a digit, and doesn't match when we get back +nan or +inf
|
||||
if (buf[0] < '0' && buf[1] <= '9' && (flags & PF_FLAG_ZERO_PAD)) {
|
||||
chrs += pfenv_print_strn(pfenv, &buf[0], 1, 0, 1);
|
||||
s++;
|
||||
width--;
|
||||
len--;
|
||||
}
|
||||
if (*s < '0' || *s >= '9') {
|
||||
// For inf or nan, we don't want to zero pad.
|
||||
flags &= ~PF_FLAG_ZERO_PAD;
|
||||
}
|
||||
chrs += pfenv_print_strn(pfenv, s, len, flags, width);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
pfenv->print_strn(pfenv->data, fmt, 1);
|
||||
chrs += 1;
|
||||
break;
|
||||
}
|
||||
++fmt;
|
||||
}
|
||||
return chrs;
|
||||
}
|
||||
|
||||
void stdout_print_strn(void *data, const char *str, unsigned int len) {
|
||||
// send stdout to USART, USB CDC VCP, and LCD if nothing else
|
||||
bool any = false;
|
||||
|
||||
if (pyb_usart_global_debug != PYB_USART_NONE) {
|
||||
usart_tx_strn_cooked(pyb_usart_global_debug, str, len);
|
||||
any = true;
|
||||
}
|
||||
if (usb_vcp_is_enabled()) {
|
||||
usb_vcp_send_strn_cooked(str, len);
|
||||
any = true;
|
||||
}
|
||||
if (!any) {
|
||||
#if MICROPY_HW_HAS_LCD
|
||||
lcd_print_strn(str, len);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static const pfenv_t pfenv_stdout = {0, stdout_print_strn};
|
||||
|
||||
int printf(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int ret = pfenv_printf(&pfenv_stdout, fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vprintf(const char *fmt, va_list ap) {
|
||||
return pfenv_printf(&pfenv_stdout, fmt, ap);
|
||||
}
|
||||
|
||||
#if MICROPY_DEBUG_PRINTERS
|
||||
int DEBUG_printf(const char *fmt, ...) {
|
||||
(void)stream;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int ret = pfenv_printf(&pfenv_stdout, fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
// need this because gcc optimises printf("%c", c) -> putchar(c), and printf("a") -> putchar('a')
|
||||
int putchar(int c) {
|
||||
char chr = c;
|
||||
stdout_print_strn(0, &chr, 1);
|
||||
return chr;
|
||||
}
|
||||
|
||||
// need this because gcc optimises printf("string\n") -> puts("string")
|
||||
int puts(const char *s) {
|
||||
stdout_print_strn(0, s, strlen(s));
|
||||
char chr = '\n';
|
||||
stdout_print_strn(0, &chr, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef struct _strn_pfenv_t {
|
||||
char *cur;
|
||||
size_t remain;
|
||||
} strn_pfenv_t;
|
||||
|
||||
void strn_print_strn(void *data, const char *str, unsigned int len) {
|
||||
strn_pfenv_t *strn_pfenv = data;
|
||||
if (len > strn_pfenv->remain) {
|
||||
len = strn_pfenv->remain;
|
||||
}
|
||||
memcpy(strn_pfenv->cur, str, len);
|
||||
strn_pfenv->cur += len;
|
||||
strn_pfenv->remain -= len;
|
||||
}
|
||||
|
||||
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap) {
|
||||
strn_pfenv_t strn_pfenv;
|
||||
strn_pfenv.cur = str;
|
||||
strn_pfenv.remain = size;
|
||||
pfenv_t pfenv;
|
||||
pfenv.data = &strn_pfenv;
|
||||
pfenv.print_strn = strn_print_strn;
|
||||
int len = pfenv_printf(&pfenv, fmt, ap);
|
||||
// add terminating null byte
|
||||
if (size > 0) {
|
||||
if (strn_pfenv.remain == 0) {
|
||||
strn_pfenv.cur[-1] = 0;
|
||||
} else {
|
||||
strn_pfenv.cur[0] = 0;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int snprintf(char *str, size_t size, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int ret = vsnprintf(str, size, fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
291
stm/pybmodule.c
291
stm/pybmodule.c
@ -1,291 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_rcc.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "ff.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "gc.h"
|
||||
#include "gccollect.h"
|
||||
#include "systick.h"
|
||||
#include "rtc.h"
|
||||
#include "pyexec.h"
|
||||
#include "servo.h"
|
||||
#include "storage.h"
|
||||
#include "usb.h"
|
||||
#include "usrsw.h"
|
||||
#include "sdcard.h"
|
||||
#include "accel.h"
|
||||
#include "led.h"
|
||||
#include "i2c.h"
|
||||
#include "usart.h"
|
||||
#include "adc.h"
|
||||
#include "audio.h"
|
||||
#include "pin.h"
|
||||
#include "gpio.h"
|
||||
#include "exti.h"
|
||||
#include "pybmodule.h"
|
||||
|
||||
// get lots of info about the board
|
||||
STATIC mp_obj_t pyb_info(void) {
|
||||
// get and print unique id; 96 bits
|
||||
{
|
||||
byte *id = (byte*)0x1fff7a10;
|
||||
printf("ID=%02x%02x%02x%02x:%02x%02x%02x%02x:%02x%02x%02x%02x\n", id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], id[8], id[9], id[10], id[11]);
|
||||
}
|
||||
|
||||
// get and print clock speeds
|
||||
// SYSCLK=168MHz, HCLK=168MHz, PCLK1=42MHz, PCLK2=84MHz
|
||||
{
|
||||
RCC_ClocksTypeDef rcc_clocks;
|
||||
RCC_GetClocksFreq(&rcc_clocks);
|
||||
printf("S=%lu\nH=%lu\nP1=%lu\nP2=%lu\n", rcc_clocks.SYSCLK_Frequency, rcc_clocks.HCLK_Frequency, rcc_clocks.PCLK1_Frequency, rcc_clocks.PCLK2_Frequency);
|
||||
}
|
||||
|
||||
// to print info about memory
|
||||
{
|
||||
printf("_text_end=%p\n", &_text_end);
|
||||
printf("_data_start_init=%p\n", &_data_start_init);
|
||||
printf("_data_start=%p\n", &_data_start);
|
||||
printf("_data_end=%p\n", &_data_end);
|
||||
printf("_bss_start=%p\n", &_bss_start);
|
||||
printf("_bss_end=%p\n", &_bss_end);
|
||||
printf("_stack_end=%p\n", &_stack_end);
|
||||
printf("_ram_start=%p\n", &_ram_start);
|
||||
printf("_heap_start=%p\n", &_heap_start);
|
||||
printf("_heap_end=%p\n", &_heap_end);
|
||||
printf("_ram_end=%p\n", &_ram_end);
|
||||
}
|
||||
|
||||
// qstr info
|
||||
{
|
||||
uint n_pool, n_qstr, n_str_data_bytes, n_total_bytes;
|
||||
qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes);
|
||||
printf("qstr:\n n_pool=%u\n n_qstr=%u\n n_str_data_bytes=%u\n n_total_bytes=%u\n", n_pool, n_qstr, n_str_data_bytes, n_total_bytes);
|
||||
}
|
||||
|
||||
// GC info
|
||||
{
|
||||
gc_info_t info;
|
||||
gc_info(&info);
|
||||
printf("GC:\n");
|
||||
printf(" %lu total\n", info.total);
|
||||
printf(" %lu : %lu\n", info.used, info.free);
|
||||
printf(" 1=%lu 2=%lu m=%lu\n", info.num_1block, info.num_2block, info.max_block);
|
||||
}
|
||||
|
||||
// free space on flash
|
||||
{
|
||||
DWORD nclst;
|
||||
FATFS *fatfs;
|
||||
f_getfree("0:", &nclst, &fatfs);
|
||||
printf("LFS free: %u bytes\n", (uint)(nclst * fatfs->csize * 512));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_info_obj, pyb_info);
|
||||
|
||||
// sync all file systems
|
||||
STATIC mp_obj_t pyb_sync(void) {
|
||||
storage_flush();
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_sync_obj, pyb_sync);
|
||||
|
||||
STATIC mp_obj_t pyb_millis(void) {
|
||||
return mp_obj_new_int(sys_tick_counter);
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_millis_obj, pyb_millis);
|
||||
|
||||
STATIC mp_obj_t pyb_delay(mp_obj_t count) {
|
||||
sys_tick_delay_ms(mp_obj_get_int(count));
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_delay_obj, pyb_delay);
|
||||
|
||||
STATIC mp_obj_t pyb_udelay(mp_obj_t usec) {
|
||||
uint32_t count = 0;
|
||||
const uint32_t utime = (168 * mp_obj_get_int(usec) / 5);
|
||||
for (;;) {
|
||||
if (++count > utime) {
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_udelay_obj, pyb_udelay);
|
||||
|
||||
STATIC mp_obj_t pyb_rng_get(void) {
|
||||
return mp_obj_new_int(RNG_GetRandomNumber() >> 16);
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_rng_get_obj, pyb_rng_get);
|
||||
|
||||
STATIC void SYSCLKConfig_STOP(void) {
|
||||
/* After wake-up from STOP reconfigure the system clock */
|
||||
/* Enable HSE */
|
||||
RCC_HSEConfig(RCC_HSE_ON);
|
||||
|
||||
/* Wait till HSE is ready */
|
||||
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) {
|
||||
}
|
||||
|
||||
/* Enable PLL */
|
||||
RCC_PLLCmd(ENABLE);
|
||||
|
||||
/* Wait till PLL is ready */
|
||||
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {
|
||||
}
|
||||
|
||||
/* Select PLL as system clock source */
|
||||
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
|
||||
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while (RCC_GetSYSCLKSource() != 0x08) {
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_stop(void) {
|
||||
PWR_EnterSTANDBYMode();
|
||||
//PWR_FlashPowerDownCmd(ENABLE); don't know what the logic is with this
|
||||
|
||||
/* Enter Stop Mode */
|
||||
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
|
||||
|
||||
/* Configures system clock after wake-up from STOP: enable HSE, PLL and select
|
||||
* PLL as system clock source (HSE and PLL are disabled in STOP mode) */
|
||||
SYSCLKConfig_STOP();
|
||||
|
||||
//PWR_FlashPowerDownCmd(DISABLE);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_stop_obj, pyb_stop);
|
||||
|
||||
STATIC mp_obj_t pyb_standby(void) {
|
||||
PWR_EnterSTANDBYMode();
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_standby_obj, pyb_standby);
|
||||
|
||||
STATIC mp_obj_t pyb_hid_send_report(mp_obj_t arg) {
|
||||
mp_obj_t *items;
|
||||
mp_obj_get_array_fixed_n(arg, 4, &items);
|
||||
uint8_t data[4];
|
||||
data[0] = mp_obj_get_int(items[0]);
|
||||
data[1] = mp_obj_get_int(items[1]);
|
||||
data[2] = mp_obj_get_int(items[2]);
|
||||
data[3] = mp_obj_get_int(items[3]);
|
||||
usb_hid_send_report(data);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(pyb_hid_send_report_obj, pyb_hid_send_report);
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(pyb_I2C_obj, pyb_I2C); // TODO put this in i2c.c
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_source_dir_obj); // defined in main.c
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_main_obj); // defined in main.c
|
||||
|
||||
STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&pyb_info_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_gc), (mp_obj_t)&pyb_gc_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_repl_info), (mp_obj_t)&pyb_set_repl_info_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stop), (mp_obj_t)&pyb_stop_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_standby), (mp_obj_t)&pyb_standby_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_source_dir), (mp_obj_t)&pyb_source_dir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_main), (mp_obj_t)&pyb_main_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_millis), (mp_obj_t)&pyb_millis_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&pyb_delay_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&pyb_udelay_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&pyb_sync_obj },
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rand), (mp_obj_t)&pyb_rng_get_obj },
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_ENABLE_RTC
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&pyb_rtc_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rtc_info), (mp_obj_t)&pyb_rtc_info_obj },
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_ENABLE_SERVO
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pwm), (mp_obj_t)&pyb_pwm_set_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_servo), (mp_obj_t)&pyb_servo_set_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Servo), (mp_obj_t)&pyb_Servo_obj },
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_HAS_SWITCH
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_switch), (mp_obj_t)&pyb_switch_obj },
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sdcard_obj },
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_HAS_MMA7660
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_accel), (mp_obj_t)&pyb_accel_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_accel_read), (mp_obj_t)&pyb_accel_read_all_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_accel_mode), (mp_obj_t)&pyb_accel_write_mode_obj },
|
||||
#endif
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_hid), (mp_obj_t)&pyb_hid_send_report_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Led), (mp_obj_t)&pyb_Led_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_I2C_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Usart), (mp_obj_t)&pyb_Usart_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ADC_all), (mp_obj_t)&pyb_ADC_all_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ADC), (mp_obj_t)&pyb_ADC_obj },
|
||||
|
||||
#if MICROPY_HW_ENABLE_AUDIO
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Audio), (mp_obj_t)&pyb_Audio_obj },
|
||||
#endif
|
||||
|
||||
// pin mapper
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_map_obj },
|
||||
|
||||
// GPIO bindings
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_gpio), (mp_obj_t)&pyb_gpio_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_gpio_in), (mp_obj_t)&pyb_gpio_input_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_gpio_out), (mp_obj_t)&pyb_gpio_output_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_NONE), MP_OBJ_NEW_SMALL_INT(GPIO_PuPd_NOPULL) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PuPd_UP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PuPd_DOWN) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PUSH_PULL), MP_OBJ_NEW_SMALL_INT(GPIO_OType_PP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OPEN_DRAIN), MP_OBJ_NEW_SMALL_INT(GPIO_OType_OD) },
|
||||
|
||||
// EXTI bindings
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Exti), (mp_obj_t)&exti_obj_type },
|
||||
};
|
||||
|
||||
STATIC const mp_obj_dict_t pyb_module_globals = {
|
||||
.base = {&mp_type_dict},
|
||||
.map = {
|
||||
.all_keys_are_qstrs = 1,
|
||||
.table_is_fixed_array = 1,
|
||||
.used = sizeof(pyb_module_globals_table) / sizeof(mp_map_elem_t),
|
||||
.alloc = sizeof(pyb_module_globals_table) / sizeof(mp_map_elem_t),
|
||||
.table = (mp_map_elem_t*)pyb_module_globals_table,
|
||||
},
|
||||
};
|
||||
|
||||
const mp_obj_module_t pyb_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_pyb,
|
||||
.globals = (mp_obj_dict_t*)&pyb_module_globals,
|
||||
};
|
@ -1 +0,0 @@
|
||||
extern const mp_obj_module_t pyb_module;
|
389
stm/pybwlan.c
389
stm/pybwlan.c
@ -1,389 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_rcc.h>
|
||||
#include <stm32f4xx_gpio.h>
|
||||
#include <stm32f4xx_tim.h>
|
||||
#include <stm32f4xx_pwr.h>
|
||||
#include <stm32f4xx_rtc.h>
|
||||
#include <stm32f4xx_usart.h>
|
||||
#include <stm_misc.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "systick.h"
|
||||
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "lexer.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
#include "cc3k/ccspi.h"
|
||||
#include "cc3k/hci.h"
|
||||
#include "cc3k/socket.h"
|
||||
#include "cc3k/netapp.h"
|
||||
#include "cc3k/wlan.h"
|
||||
#include "cc3k/nvmem.h"
|
||||
|
||||
mp_obj_t pyb_wlan_connect(uint n_args, const mp_obj_t *args) {
|
||||
const char *ap;
|
||||
const char *key;
|
||||
if (n_args == 2) {
|
||||
ap = qstr_str(mp_obj_get_qstr(args[0]));
|
||||
key = qstr_str(mp_obj_get_qstr(args[1]));
|
||||
} else {
|
||||
ap = "your-ssid";
|
||||
key = "your-password";
|
||||
}
|
||||
// might want to set wlan_ioctl_set_connection_policy
|
||||
int ret = wlan_connect(WLAN_SEC_WPA2, ap, strlen(ap), NULL, (byte*)key, strlen(key));
|
||||
return mp_obj_new_int(ret);
|
||||
}
|
||||
|
||||
mp_obj_t pyb_wlan_disconnect(void) {
|
||||
int ret = wlan_disconnect();
|
||||
return mp_obj_new_int(ret);
|
||||
}
|
||||
|
||||
mp_obj_t decode_addr(unsigned char *ip, int n_bytes) {
|
||||
char data[64] = "";
|
||||
if (n_bytes == 4) {
|
||||
snprintf(data, 64, "%u.%u.%u.%u", ip[3], ip[2], ip[1], ip[0]);
|
||||
} else if (n_bytes == 6) {
|
||||
snprintf(data, 64, "%02x:%02x:%02x:%02x:%02x:%02x", ip[5], ip[4], ip[3], ip[2], ip[1], ip[0]);
|
||||
} else if (n_bytes == 32) {
|
||||
snprintf(data, 64, "%s", ip);
|
||||
}
|
||||
return mp_obj_new_str(qstr_from_strn(data, strlen(data)));
|
||||
}
|
||||
|
||||
void decode_addr_and_store(mp_obj_t object, qstr q_attr, unsigned char *ip, int n_bytes) {
|
||||
rt_store_attr(object, q_attr, decode_addr(ip, n_bytes));
|
||||
}
|
||||
|
||||
static mp_obj_t net_address_type = MP_OBJ_NULL;
|
||||
|
||||
mp_obj_t pyb_wlan_get_ip(void) {
|
||||
tNetappIpconfigRetArgs ipconfig;
|
||||
netapp_ipconfig(&ipconfig);
|
||||
|
||||
// If byte 1 is 0 we don't have a valid address
|
||||
if (ipconfig.aucIP[3] == 0) {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
// if it doesn't already exist, make a new empty class for NetAddress objects
|
||||
if (net_address_type == MP_OBJ_NULL) {
|
||||
net_address_type = mp_obj_new_type(QSTR_FROM_STR_STATIC("NetAddress"), mp_const_empty_tuple, mp_obj_new_dict(0));
|
||||
}
|
||||
|
||||
// make a new NetAddress object
|
||||
mp_obj_t net_addr = rt_call_function_0(net_address_type);
|
||||
|
||||
// fill the NetAddress object with data
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("ip"), &ipconfig.aucIP[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("subnet"), &ipconfig.aucSubnetMask[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("gateway"), &ipconfig.aucDefaultGateway[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("dhcp"), &ipconfig.aucDHCPServer[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("dns"), &ipconfig.aucDNSServer[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("mac"), &ipconfig.uaMacAddr[0], 6);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("ssid"), &ipconfig.uaSSID[0], 32);
|
||||
|
||||
return net_addr;
|
||||
}
|
||||
|
||||
uint32_t last_ip = 0; // XXX such a hack!
|
||||
mp_obj_t pyb_wlan_get_host(mp_obj_t host_name) {
|
||||
const char *host = qstr_str(mp_obj_get_qstr(host_name));
|
||||
uint32_t ip;
|
||||
if (gethostbyname(host, strlen(host), &ip) < 0) {
|
||||
printf("gethostbyname failed\n");
|
||||
return mp_const_none;
|
||||
}
|
||||
if (ip == 0) {
|
||||
// unknown host
|
||||
return mp_const_none;
|
||||
}
|
||||
last_ip = ip;
|
||||
byte ip_data[4];
|
||||
ip_data[0] = ((ip >> 0) & 0xff);
|
||||
ip_data[1] = ((ip >> 8) & 0xff);
|
||||
ip_data[2] = ((ip >> 16) & 0xff);
|
||||
ip_data[3] = ((ip >> 24) & 0xff);
|
||||
return decode_addr(ip_data, 4);
|
||||
}
|
||||
|
||||
mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) {
|
||||
if (host_name == mp_const_none) {
|
||||
last_ip = (192 << 24) | (168 << 16) | (0 << 8) | (3);
|
||||
} else {
|
||||
if (pyb_wlan_get_host(host_name) == mp_const_none) {
|
||||
nlr_raise(mp_obj_new_exception_msg(QSTR_FROM_STR_STATIC("WlanError"), "unknown host"));
|
||||
}
|
||||
}
|
||||
int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (sd < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(QSTR_FROM_STR_STATIC("WlanError"), "socket failed: %d", sd));
|
||||
}
|
||||
//printf("socket seemed to work\n");
|
||||
//sys_tick_delay_ms(200);
|
||||
sockaddr_in remote;
|
||||
memset(&remote, 0, sizeof(sockaddr_in));
|
||||
remote.sin_family = AF_INET;
|
||||
remote.sin_port = htons(80);
|
||||
remote.sin_addr.s_addr = htonl(last_ip);
|
||||
int ret = connect(sd, (sockaddr*)&remote, sizeof(sockaddr));
|
||||
if (ret != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(QSTR_FROM_STR_STATIC("WlanError"), "connect failed: %d", ret));
|
||||
}
|
||||
//printf("connect seemed to work\n");
|
||||
//sys_tick_delay_ms(200);
|
||||
|
||||
vstr_t *vstr = vstr_new();
|
||||
vstr_printf(vstr, "GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: PYBv2\r\n\r\n", qstr_str(mp_obj_get_qstr(host_path)), qstr_str(mp_obj_get_qstr(host_name)));
|
||||
const char *query = vstr_str(vstr);
|
||||
|
||||
// send query
|
||||
{
|
||||
int sent = 0;
|
||||
while (sent < strlen(query)) {
|
||||
/*
|
||||
extern void SpiIntGPIOHandler(void);
|
||||
SpiIntGPIOHandler();
|
||||
*/
|
||||
//printf("sending %d bytes\n", strlen(query + sent));
|
||||
ret = send(sd, query + sent, strlen(query + sent), 0);
|
||||
//printf("sent %d bytes\n", ret);
|
||||
if (ret < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(QSTR_FROM_STR_STATIC("WlanError"), "send failed"));
|
||||
}
|
||||
sent += ret;
|
||||
//sys_tick_delay_ms(200);
|
||||
}
|
||||
}
|
||||
|
||||
//printf("send seemed to work!\n");
|
||||
//sys_tick_delay_ms(5000);
|
||||
|
||||
// receive reply
|
||||
mp_obj_t mp_ret = mp_const_none;
|
||||
{
|
||||
//printf("doing receive\n");
|
||||
char buf[64];
|
||||
vstr_reset(vstr);
|
||||
|
||||
for (;;) {
|
||||
// do a select() call on this socket
|
||||
timeval timeout;
|
||||
fd_set fd_read;
|
||||
|
||||
memset(&fd_read, 0, sizeof(fd_read));
|
||||
FD_SET(sd, &fd_read);
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 500000; // 500 millisec
|
||||
|
||||
int s = select(sd+1, &fd_read, NULL, NULL, &timeout);
|
||||
if (s == 0) {
|
||||
// no data available
|
||||
break;
|
||||
}
|
||||
|
||||
// read data
|
||||
ret = recv(sd, buf, 64, 0);
|
||||
if (ret < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(QSTR_FROM_STR_STATIC("WlanError"), "recv failed %d", ret));
|
||||
}
|
||||
vstr_add_strn(vstr, buf, ret);
|
||||
}
|
||||
|
||||
mp_ret = mp_obj_new_str(qstr_from_strn_take(vstr->buf, vstr->alloc, vstr->len));
|
||||
}
|
||||
|
||||
closesocket(sd);
|
||||
|
||||
return mp_ret;
|
||||
}
|
||||
|
||||
mp_obj_t pyb_wlan_serve(void) {
|
||||
printf("serve socket\n");
|
||||
int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
printf("serve socket got %d\n", sd);
|
||||
sys_tick_delay_ms(500);
|
||||
if (sd < 0) {
|
||||
printf("socket fail\n");
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(QSTR_FROM_STR_STATIC("WlanError"), "socket failed: %d", sd));
|
||||
}
|
||||
|
||||
/*
|
||||
if (setsockopt(sd, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, SOCK_ON, sizeof(SOCK_ON)) < 0) {
|
||||
printf("couldn't set socket as non-blocking\n");
|
||||
return mp_const_none;
|
||||
}
|
||||
*/
|
||||
|
||||
sockaddr_in remote;
|
||||
memset(&remote, 0, sizeof(sockaddr_in));
|
||||
remote.sin_family = AF_INET;
|
||||
remote.sin_port = htons(8080);
|
||||
remote.sin_addr.s_addr = htonl(0);
|
||||
printf("serve bind\n");
|
||||
int ret = bind(sd, (sockaddr*)&remote, sizeof(sockaddr));
|
||||
printf("serve bind got %d\n", ret);
|
||||
sys_tick_delay_ms(100);
|
||||
if (ret != 0) {
|
||||
printf("bind fail\n");
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(QSTR_FROM_STR_STATIC("WlanError"), "bind failed: %d", ret));
|
||||
}
|
||||
printf("bind seemed to work\n");
|
||||
|
||||
// listen
|
||||
ret = listen(sd, 0);
|
||||
printf("listen = %d\n", ret);
|
||||
sys_tick_delay_ms(100);
|
||||
|
||||
// accept connections
|
||||
int fd = -1;
|
||||
for (;;) {
|
||||
sockaddr accept_addr;
|
||||
socklen_t accept_len;
|
||||
fd = accept(sd, &accept_addr, &accept_len);
|
||||
printf("accept = %d\n", fd);
|
||||
sys_tick_delay_ms(500);
|
||||
if (fd >= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// receive some data
|
||||
{
|
||||
printf("receiving on sd=%d fd=%d\n", sd, fd);
|
||||
char buf[64];
|
||||
ret = recv(fd, buf, 64, 0);
|
||||
printf("recv = %d\n", ret);
|
||||
if (ret > 0) {
|
||||
printf("****%.*s****\n", ret, buf);
|
||||
}
|
||||
sys_tick_delay_ms(100);
|
||||
}
|
||||
|
||||
// send some data
|
||||
ret = send(fd, "test data!", 10, 0);
|
||||
printf("send = %d\n", ret);
|
||||
sys_tick_delay_ms(100);
|
||||
|
||||
closesocket(fd);
|
||||
closesocket(sd);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! CC3000_UsynchCallback
|
||||
//!
|
||||
//! @param lEventType Event type
|
||||
//! @param data
|
||||
//! @param length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief The function handles asynchronous events that come from CC3000
|
||||
//! device and operates a led for indicate
|
||||
//
|
||||
//*****************************************************************************
|
||||
void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length)
|
||||
{
|
||||
if (lEventType == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE)
|
||||
{
|
||||
//ulSmartConfigFinished = 1;
|
||||
//ucStopSmartConfig = 1;
|
||||
printf("WLAN: simple config done\n");
|
||||
}
|
||||
|
||||
if (lEventType == HCI_EVNT_WLAN_UNSOL_CONNECT)
|
||||
{
|
||||
//ulCC3000Connected = 1;
|
||||
printf("WLAN unsol connect\n");
|
||||
}
|
||||
|
||||
if (lEventType == HCI_EVNT_WLAN_UNSOL_DISCONNECT)
|
||||
{
|
||||
//ulCC3000Connected = 0;
|
||||
//ulCC3000DHCP = 0;
|
||||
//ulCC3000DHCP_configured = 0;
|
||||
printf("WLAN unsol disconnect\n");
|
||||
}
|
||||
|
||||
if (lEventType == HCI_EVNT_WLAN_UNSOL_DHCP)
|
||||
{
|
||||
//ulCC3000DHCP = 1;
|
||||
printf("WLAN unsol DHCP\n");
|
||||
}
|
||||
|
||||
if (lEventType == HCI_EVENT_CC3000_CAN_SHUT_DOWN)
|
||||
{
|
||||
//OkToDoShutDown = 1;
|
||||
printf("WLAN can shut down\n");
|
||||
}
|
||||
|
||||
if (lEventType == HCI_EVNT_WLAN_ASYNC_PING_REPORT)
|
||||
{
|
||||
printf("WLAN async ping report\n");
|
||||
//PRINT_F("CC3000: Ping report\n\r");
|
||||
//pingReportnum++;
|
||||
//memcpy(&pingReport, data, length);
|
||||
}
|
||||
|
||||
if (lEventType == HCI_EVNT_BSD_TCP_CLOSE_WAIT) {
|
||||
printf("WLAN bsd tcp close wait\n");
|
||||
/*
|
||||
uint8_t socketnum;
|
||||
socketnum = data[0];
|
||||
//PRINT_F("TCP Close wait #"); printDec(socketnum);
|
||||
if (socketnum < MAX_SOCKETS)
|
||||
closed_sockets[socketnum] = true;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void pyb_wlan_init(void) {
|
||||
SpiInit();
|
||||
wlan_init(CC3000_UsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch, ReadWlanInterruptPin, WlanInterruptEnable, WlanInterruptDisable, WriteWlanPin);
|
||||
|
||||
mp_obj_t m = mp_obj_new_module(QSTR_FROM_STR_STATIC("wlan"));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("connect"), rt_make_function_var(0, pyb_wlan_connect));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("disconnect"), rt_make_function_n(0, pyb_wlan_disconnect));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("ip"), rt_make_function_n(0, pyb_wlan_get_ip));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("get_host"), rt_make_function_n(1, pyb_wlan_get_host));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("http_get"), rt_make_function_n(2, pyb_wlan_http_get));
|
||||
rt_store_attr(m, QSTR_FROM_STR_STATIC("serve"), rt_make_function_n(0, pyb_wlan_serve));
|
||||
rt_store_name(QSTR_FROM_STR_STATIC("wlan"), m);
|
||||
}
|
||||
|
||||
void pyb_wlan_start(void) {
|
||||
wlan_start(0);
|
||||
|
||||
// TODO: check return value !=0
|
||||
|
||||
wlan_ioctl_set_connection_policy(0, 0, 0); // don't auto-connect
|
||||
wlan_ioctl_del_profile(255); // delete stored eeprom data
|
||||
|
||||
// Mask out all non-required events from CC3000
|
||||
wlan_set_event_mask(HCI_EVNT_WLAN_UNSOL_INIT |
|
||||
//HCI_EVNT_WLAN_ASYNC_PING_REPORT |// we want ping reports
|
||||
//HCI_EVNT_BSD_TCP_CLOSE_WAIT |
|
||||
//HCI_EVNT_WLAN_TX_COMPLETE |
|
||||
HCI_EVNT_WLAN_KEEPALIVE);
|
||||
|
||||
/*
|
||||
byte ver[2];
|
||||
int ret = nvmem_read_sp_version(ver);
|
||||
printf("nvmem_read_sp_version=%d; %02x %02x\n", ret, ver[0], ver[1]);
|
||||
*/
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
void pyb_wlan_init(void);
|
||||
void pyb_wlan_start(void);
|
318
stm/pyexec.c
318
stm/pyexec.c
@ -1,318 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "misc.h"
|
||||
#include "lexer.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "parsehelper.h"
|
||||
#include "compile.h"
|
||||
#include "runtime.h"
|
||||
#include "repl.h"
|
||||
#include "gc.h"
|
||||
#include "gccollect.h"
|
||||
#include "systick.h"
|
||||
#include "pyexec.h"
|
||||
#include "storage.h"
|
||||
#include "usb.h"
|
||||
#include "usart.h"
|
||||
|
||||
static bool repl_display_debugging_info = 0;
|
||||
|
||||
void stdout_tx_str(const char *str) {
|
||||
if (pyb_usart_global_debug != PYB_USART_NONE) {
|
||||
usart_tx_str(pyb_usart_global_debug, str);
|
||||
}
|
||||
#if defined(USE_HOST_MODE) && MICROPY_HW_HAS_LCD
|
||||
lcd_print_str(str);
|
||||
#endif
|
||||
usb_vcp_send_str(str);
|
||||
}
|
||||
|
||||
int stdin_rx_chr(void) {
|
||||
for (;;) {
|
||||
#ifdef USE_HOST_MODE
|
||||
pyb_usb_host_process();
|
||||
int c = pyb_usb_host_get_keyboard();
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
if (usb_vcp_rx_any() != 0) {
|
||||
return usb_vcp_rx_get();
|
||||
} else if (pyb_usart_global_debug != PYB_USART_NONE && usart_rx_any(pyb_usart_global_debug)) {
|
||||
return usart_rx_char(pyb_usart_global_debug);
|
||||
}
|
||||
sys_tick_delay_ms(1);
|
||||
if (storage_needs_flush()) {
|
||||
storage_flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *str_dup(const char *str) {
|
||||
uint32_t len = strlen(str);
|
||||
char *s2 = m_new(char, len + 1);
|
||||
memcpy(s2, str, len);
|
||||
s2[len] = 0;
|
||||
return s2;
|
||||
}
|
||||
|
||||
#define READLINE_HIST_SIZE (8)
|
||||
|
||||
static const char *readline_hist[READLINE_HIST_SIZE] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
||||
|
||||
int readline(vstr_t *line, const char *prompt) {
|
||||
stdout_tx_str(prompt);
|
||||
int len = vstr_len(line);
|
||||
int escape = 0;
|
||||
int hist_num = 0;
|
||||
for (;;) {
|
||||
int c = stdin_rx_chr();
|
||||
if (escape == 0) {
|
||||
if (VCP_CHAR_CTRL_A <= c && c <= VCP_CHAR_CTRL_D && vstr_len(line) == len) {
|
||||
return c;
|
||||
} else if (c == '\r') {
|
||||
stdout_tx_str("\r\n");
|
||||
for (int i = READLINE_HIST_SIZE - 1; i > 0; i--) {
|
||||
readline_hist[i] = readline_hist[i - 1];
|
||||
}
|
||||
readline_hist[0] = str_dup(vstr_str(line));
|
||||
return 0;
|
||||
} else if (c == 27) {
|
||||
escape = true;
|
||||
} else if (c == 127) {
|
||||
if (vstr_len(line) > len) {
|
||||
vstr_cut_tail_bytes(line, 1);
|
||||
stdout_tx_str("\b \b");
|
||||
}
|
||||
} else if (32 <= c && c <= 126) {
|
||||
vstr_add_char(line, c);
|
||||
stdout_tx_str(line->buf + line->len - 1);
|
||||
}
|
||||
} else if (escape == 1) {
|
||||
if (c == '[') {
|
||||
escape = 2;
|
||||
} else {
|
||||
escape = 0;
|
||||
}
|
||||
} else if (escape == 2) {
|
||||
escape = 0;
|
||||
if (c == 'A') {
|
||||
// up arrow
|
||||
if (hist_num < READLINE_HIST_SIZE && readline_hist[hist_num] != NULL) {
|
||||
// erase line
|
||||
for (int i = line->len - len; i > 0; i--) {
|
||||
stdout_tx_str("\b \b");
|
||||
}
|
||||
// set line to history
|
||||
line->len = len;
|
||||
vstr_add_str(line, readline_hist[hist_num]);
|
||||
// draw line
|
||||
stdout_tx_str(readline_hist[hist_num]);
|
||||
// increase hist num
|
||||
hist_num += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
escape = 0;
|
||||
}
|
||||
sys_tick_delay_ms(1);
|
||||
}
|
||||
}
|
||||
|
||||
// parses, compiles and executes the code in the lexer
|
||||
// frees the lexer before returning
|
||||
bool parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) {
|
||||
mp_parse_error_kind_t parse_error_kind;
|
||||
mp_parse_node_t pn = mp_parse(lex, input_kind, &parse_error_kind);
|
||||
qstr source_name = mp_lexer_source_name(lex);
|
||||
|
||||
if (pn == MP_PARSE_NODE_NULL) {
|
||||
// parse error
|
||||
mp_parse_show_exception(lex, parse_error_kind);
|
||||
mp_lexer_free(lex);
|
||||
return false;
|
||||
}
|
||||
|
||||
mp_lexer_free(lex);
|
||||
|
||||
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, is_repl);
|
||||
mp_parse_node_free(pn);
|
||||
|
||||
if (module_fun == mp_const_none) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nlr_buf_t nlr;
|
||||
bool ret;
|
||||
uint32_t start = sys_tick_counter;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
usb_vcp_set_interrupt_char(VCP_CHAR_CTRL_C); // allow ctrl-C to interrupt us
|
||||
mp_call_function_0(module_fun);
|
||||
usb_vcp_set_interrupt_char(VCP_CHAR_NONE); // disable interrupt
|
||||
nlr_pop();
|
||||
ret = true;
|
||||
} else {
|
||||
// uncaught exception
|
||||
// FIXME it could be that an interrupt happens just before we disable it here
|
||||
usb_vcp_set_interrupt_char(VCP_CHAR_NONE); // disable interrupt
|
||||
mp_obj_print_exception((mp_obj_t)nlr.ret_val);
|
||||
ret = false;
|
||||
}
|
||||
|
||||
// display debugging info if wanted
|
||||
if (is_repl && repl_display_debugging_info) {
|
||||
uint32_t ticks = sys_tick_counter - start; // TODO implement a function that does this properly
|
||||
printf("took %lu ms\n", ticks);
|
||||
gc_collect();
|
||||
// qstr info
|
||||
{
|
||||
uint n_pool, n_qstr, n_str_data_bytes, n_total_bytes;
|
||||
qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes);
|
||||
printf("qstr:\n n_pool=%u\n n_qstr=%u\n n_str_data_bytes=%u\n n_total_bytes=%u\n", n_pool, n_qstr, n_str_data_bytes, n_total_bytes);
|
||||
}
|
||||
|
||||
// GC info
|
||||
{
|
||||
gc_info_t info;
|
||||
gc_info(&info);
|
||||
printf("GC:\n");
|
||||
printf(" %lu total\n", info.total);
|
||||
printf(" %lu : %lu\n", info.used, info.free);
|
||||
printf(" 1=%lu 2=%lu m=%lu\n", info.num_1block, info.num_2block, info.max_block);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void pyexec_raw_repl(void) {
|
||||
vstr_t line;
|
||||
vstr_init(&line, 32);
|
||||
|
||||
raw_repl_reset:
|
||||
stdout_tx_str("raw REPL; CTRL-C to exit\r\n");
|
||||
|
||||
for (;;) {
|
||||
vstr_reset(&line);
|
||||
stdout_tx_str(">");
|
||||
for (;;) {
|
||||
char c = stdin_rx_chr();
|
||||
if (c == VCP_CHAR_CTRL_A) {
|
||||
goto raw_repl_reset;
|
||||
} else if (c == VCP_CHAR_CTRL_C) {
|
||||
vstr_reset(&line);
|
||||
break;
|
||||
} else if (c == VCP_CHAR_CTRL_D) {
|
||||
break;
|
||||
} else if (c == '\r') {
|
||||
vstr_add_char(&line, '\n');
|
||||
} else if (32 <= c && c <= 126) {
|
||||
vstr_add_char(&line, c);
|
||||
}
|
||||
}
|
||||
|
||||
stdout_tx_str("OK");
|
||||
|
||||
if (vstr_len(&line) == 0) {
|
||||
// finished
|
||||
break;
|
||||
}
|
||||
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0);
|
||||
parse_compile_execute(lex, MP_PARSE_FILE_INPUT, false);
|
||||
|
||||
stdout_tx_str("\004");
|
||||
}
|
||||
|
||||
vstr_clear(&line);
|
||||
stdout_tx_str("\r\n");
|
||||
}
|
||||
|
||||
void pyexec_repl(void) {
|
||||
#if defined(USE_HOST_MODE) && MICROPY_HW_HAS_LCD
|
||||
// in host mode, we enable the LCD for the repl
|
||||
mp_obj_t lcd_o = mp_call_function_0(mp_load_name(qstr_from_str("LCD")));
|
||||
mp_call_function_1(mp_load_attr(lcd_o, qstr_from_str("light")), mp_const_true);
|
||||
#endif
|
||||
|
||||
stdout_tx_str("Micro Python build <git hash> on 25/1/2014; " MICROPY_HW_BOARD_NAME " with STM32F405RG\r\n");
|
||||
stdout_tx_str("Type \"help()\" for more information.\r\n");
|
||||
|
||||
// to test ctrl-C
|
||||
/*
|
||||
{
|
||||
uint32_t x[4] = {0x424242, 0xdeaddead, 0x242424, 0xdeadbeef};
|
||||
for (;;) {
|
||||
nlr_buf_t nlr;
|
||||
printf("pyexec_repl: %p\n", x);
|
||||
usb_vcp_set_interrupt_char(VCP_CHAR_CTRL_C);
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
for (;;) {
|
||||
}
|
||||
} else {
|
||||
printf("break\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
vstr_t line;
|
||||
vstr_init(&line, 32);
|
||||
|
||||
for (;;) {
|
||||
vstr_reset(&line);
|
||||
int ret = readline(&line, ">>> ");
|
||||
|
||||
if (ret == VCP_CHAR_CTRL_A) {
|
||||
pyexec_raw_repl();
|
||||
continue;
|
||||
} else if (ret == VCP_CHAR_CTRL_C) {
|
||||
stdout_tx_str("\r\n");
|
||||
continue;
|
||||
} else if (ret == VCP_CHAR_CTRL_D) {
|
||||
// EOF
|
||||
break;
|
||||
} else if (vstr_len(&line) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while (mp_repl_continue_with_input(vstr_str(&line))) {
|
||||
vstr_add_char(&line, '\n');
|
||||
int ret = readline(&line, "... ");
|
||||
if (ret == VCP_CHAR_CTRL_D) {
|
||||
// stop entering compound statement
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0);
|
||||
parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, true);
|
||||
}
|
||||
|
||||
stdout_tx_str("\r\n");
|
||||
}
|
||||
|
||||
bool pyexec_file(const char *filename) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_file(filename);
|
||||
|
||||
if (lex == NULL) {
|
||||
printf("could not open file '%s' for reading\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
return parse_compile_execute(lex, MP_PARSE_FILE_INPUT, false);
|
||||
}
|
||||
|
||||
mp_obj_t pyb_set_repl_info(mp_obj_t o_value) {
|
||||
repl_display_debugging_info = mp_obj_get_int(o_value);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(pyb_set_repl_info_obj, pyb_set_repl_info);
|
@ -1,5 +0,0 @@
|
||||
void pyexec_raw_repl(void);
|
||||
void pyexec_repl(void);
|
||||
bool pyexec_file(const char *filename);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_set_repl_info_obj);
|
@ -1,90 +0,0 @@
|
||||
// qstrs specific to this port
|
||||
|
||||
Q(help)
|
||||
Q(pyb)
|
||||
Q(info)
|
||||
Q(sd_test)
|
||||
Q(stop)
|
||||
Q(standby)
|
||||
Q(source_dir)
|
||||
Q(main)
|
||||
Q(sync)
|
||||
Q(gc)
|
||||
Q(repl_info)
|
||||
Q(delay)
|
||||
Q(udelay)
|
||||
Q(switch)
|
||||
Q(SW)
|
||||
Q(servo)
|
||||
Q(pwm)
|
||||
Q(accel)
|
||||
Q(accel_read)
|
||||
Q(accel_mode)
|
||||
Q(hid)
|
||||
Q(time)
|
||||
Q(rand)
|
||||
Q(Led)
|
||||
Q(LCD)
|
||||
Q(Servo)
|
||||
Q(SD)
|
||||
Q(SDcard)
|
||||
Q(I2C)
|
||||
Q(gpio)
|
||||
Q(gpio_in)
|
||||
Q(gpio_out)
|
||||
Q(Usart)
|
||||
Q(ADC)
|
||||
Q(ADC_all)
|
||||
Q(Audio)
|
||||
Q(File)
|
||||
// Entries for sys.path
|
||||
Q(0:/)
|
||||
Q(0:/src)
|
||||
Q(0:/lib)
|
||||
Q(Pin)
|
||||
Q(PinMap)
|
||||
Q(PinAF)
|
||||
Q(PinNamed)
|
||||
Q(Exti)
|
||||
Q(ExtiMeta)
|
||||
Q(rtc_info)
|
||||
Q(millis)
|
||||
Q(PULL_NONE)
|
||||
Q(PULL_UP)
|
||||
Q(PULL_DOWN)
|
||||
Q(PUSH_PULL)
|
||||
Q(OPEN_DRAIN)
|
||||
Q(on)
|
||||
Q(off)
|
||||
Q(toggle)
|
||||
Q(line)
|
||||
Q(enable)
|
||||
Q(disable)
|
||||
Q(swint)
|
||||
Q(read_channel)
|
||||
Q(read_core_temp)
|
||||
Q(read_core_vbat)
|
||||
Q(read_core_vref)
|
||||
Q(noise)
|
||||
Q(triangle)
|
||||
Q(dac)
|
||||
Q(dma)
|
||||
Q(present)
|
||||
Q(power)
|
||||
Q(read)
|
||||
Q(read)
|
||||
Q(write)
|
||||
Q(close)
|
||||
Q(name)
|
||||
Q(port)
|
||||
Q(pin)
|
||||
Q(angle)
|
||||
Q(start)
|
||||
Q(write)
|
||||
Q(read)
|
||||
Q(readAndStop)
|
||||
Q(stop)
|
||||
Q(status)
|
||||
Q(recv_chr)
|
||||
Q(send_chr)
|
||||
Q(send)
|
130
stm/rtc.c
130
stm/rtc.c
@ -1,130 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stm32f4xx.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "systick.h"
|
||||
#include "rtc.h"
|
||||
|
||||
machine_uint_t rtc_info;
|
||||
|
||||
#define RTC_INFO_USE_EXISTING (0)
|
||||
#define RTC_INFO_USE_LSE (1)
|
||||
#define RTC_INFO_USE_LSI (3)
|
||||
|
||||
void rtc_init(void) {
|
||||
// Enable the PWR clock
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
|
||||
|
||||
// Allow access to RTC
|
||||
PWR_BackupAccessCmd(ENABLE);
|
||||
|
||||
if (RTC_ReadBackupRegister(RTC_BKP_DR0) == 0x32F2) {
|
||||
// RTC still alive, so don't re-init it
|
||||
// wait for RTC APB register synchronisation
|
||||
RTC_WaitForSynchro();
|
||||
rtc_info = RTC_INFO_USE_EXISTING;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t timeout = 10000000;
|
||||
|
||||
// Enable the PWR clock
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
|
||||
|
||||
// Allow access to RTC
|
||||
PWR_BackupAccessCmd(ENABLE);
|
||||
|
||||
// Enable the LSE OSC
|
||||
RCC_LSEConfig(RCC_LSE_ON);
|
||||
|
||||
// Wait till LSE is ready
|
||||
machine_uint_t sys_tick = sys_tick_counter;
|
||||
while((RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) && (--timeout > 0)) {
|
||||
}
|
||||
|
||||
// record how long it took for the RTC to start up
|
||||
rtc_info = (sys_tick_counter - sys_tick) << 2;
|
||||
|
||||
// If LSE timed out, use LSI instead
|
||||
if (timeout == 0) {
|
||||
// Disable the LSE OSC
|
||||
RCC_LSEConfig(RCC_LSE_OFF);
|
||||
|
||||
// Enable the LSI OSC
|
||||
RCC_LSICmd(ENABLE);
|
||||
|
||||
// Wait till LSI is ready
|
||||
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {
|
||||
}
|
||||
|
||||
// Use LSI as the RTC Clock Source
|
||||
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
|
||||
|
||||
// record that we are using the LSI
|
||||
rtc_info |= RTC_INFO_USE_LSI;
|
||||
} else {
|
||||
// Use LSE as the RTC Clock Source
|
||||
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
|
||||
|
||||
// record that we are using the LSE
|
||||
rtc_info |= RTC_INFO_USE_LSE;
|
||||
}
|
||||
|
||||
// Note: LSI is around (32KHz), these dividers should work either way
|
||||
// ck_spre(1Hz) = RTCCLK(LSE) /(uwAsynchPrediv + 1)*(uwSynchPrediv + 1)
|
||||
uint32_t uwSynchPrediv = 0xFF;
|
||||
uint32_t uwAsynchPrediv = 0x7F;
|
||||
|
||||
// Enable the RTC Clock
|
||||
RCC_RTCCLKCmd(ENABLE);
|
||||
|
||||
// Wait for RTC APB registers synchronisation
|
||||
RTC_WaitForSynchro();
|
||||
|
||||
// Configure the RTC data register and RTC prescaler
|
||||
RTC_InitTypeDef RTC_InitStructure;
|
||||
RTC_InitStructure.RTC_AsynchPrediv = uwAsynchPrediv;
|
||||
RTC_InitStructure.RTC_SynchPrediv = uwSynchPrediv;
|
||||
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
|
||||
RTC_Init(&RTC_InitStructure);
|
||||
|
||||
// Set the date (BCD)
|
||||
RTC_DateTypeDef RTC_DateStructure;
|
||||
RTC_DateStructure.RTC_Year = 0x13;
|
||||
RTC_DateStructure.RTC_Month = RTC_Month_October;
|
||||
RTC_DateStructure.RTC_Date = 0x26;
|
||||
RTC_DateStructure.RTC_WeekDay = RTC_Weekday_Saturday;
|
||||
RTC_SetDate(RTC_Format_BCD, &RTC_DateStructure);
|
||||
|
||||
// Set the time (BCD)
|
||||
RTC_TimeTypeDef RTC_TimeStructure;
|
||||
RTC_TimeStructure.RTC_H12 = RTC_H12_AM;
|
||||
RTC_TimeStructure.RTC_Hours = 0x01;
|
||||
RTC_TimeStructure.RTC_Minutes = 0x53;
|
||||
RTC_TimeStructure.RTC_Seconds = 0x00;
|
||||
RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure);
|
||||
|
||||
// Indicator for the RTC configuration
|
||||
RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
mp_obj_t pyb_rtc_info(void) {
|
||||
return mp_obj_new_int(rtc_info);
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_rtc_info_obj, pyb_rtc_info);
|
||||
|
||||
mp_obj_t pyb_rtc_read(void) {
|
||||
RTC_TimeTypeDef RTC_TimeStructure;
|
||||
RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);
|
||||
printf("%02d:%02d:%02d\n", RTC_TimeStructure.RTC_Hours, RTC_TimeStructure.RTC_Minutes, RTC_TimeStructure.RTC_Seconds);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_rtc_read_obj, pyb_rtc_read);
|
@ -1,4 +0,0 @@
|
||||
void rtc_init(void);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_rtc_info_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_rtc_read_obj);
|
211
stm/sdcard.c
211
stm/sdcard.c
@ -1,211 +0,0 @@
|
||||
// TODO
|
||||
// make it work with DMA
|
||||
|
||||
#include <stdio.h>
|
||||
//#include "stm32f4xx_sdio.h"
|
||||
#include "stm324x7i_eval_sdio_sd.h"
|
||||
#include "misc.h"
|
||||
#include "systick.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "sdcard.h"
|
||||
|
||||
#if 0
|
||||
#define BLOCK_SIZE 512 /* Block Size in Bytes */
|
||||
|
||||
uint8_t aBuffer_Block_Rx[BLOCK_SIZE];
|
||||
|
||||
void sdio_init(void) {
|
||||
SD_Error error = SD_Init();
|
||||
printf("Init: %x\n", error);
|
||||
uint8_t det = SD_Detect();
|
||||
printf("Detc: %x\n", det);
|
||||
|
||||
if (!det) {
|
||||
printf("no card detected\n");
|
||||
SD_PowerOFF();
|
||||
SD_DeInit();
|
||||
return;
|
||||
}
|
||||
|
||||
// read a block!
|
||||
error = SD_ReadBlock(aBuffer_Block_Rx, 512, BLOCK_SIZE);
|
||||
printf("ReadBlock: %d\n", error);
|
||||
|
||||
/*
|
||||
// Check if the Transfer is finished
|
||||
error = SD_WaitReadOperation();
|
||||
printf("WaitReadOp: %d\n", error);
|
||||
*/
|
||||
|
||||
uint32_t stc = sys_tick_counter;
|
||||
while (SD_GetStatus() != SD_TRANSFER_OK) {
|
||||
if (sys_tick_has_passed(stc, 2000)) {
|
||||
printf("timeout waiting for read to finish\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("done!!\n");
|
||||
|
||||
printf("%.16s", aBuffer_Block_Rx);
|
||||
|
||||
/*
|
||||
snprintf((char*)aBuffer_Block_Rx, BLOCK_SIZE, "Here is some data back for you!\nBLOCK_SIZE=%d\n", BLOCK_SIZE);
|
||||
error = SD_WriteBlock(aBuffer_Block_Rx, 512, BLOCK_SIZE);
|
||||
printf("WriteBlock: %d\n", error);
|
||||
|
||||
while (SD_GetStatus() != SD_TRANSFER_OK) {
|
||||
}
|
||||
printf("done writing!\n");
|
||||
*/
|
||||
|
||||
SD_PowerOFF();
|
||||
SD_DeInit();
|
||||
}
|
||||
#endif
|
||||
|
||||
void sdcard_init(void) {
|
||||
// init the SD card detect pin
|
||||
SD_LowLevel_Init_Detect();
|
||||
}
|
||||
|
||||
bool sdcard_is_present(void) {
|
||||
return SD_Detect() != 0;
|
||||
}
|
||||
|
||||
bool sdcard_power_on(void) {
|
||||
if (!SD_Detect()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SD_Error status = SD_Init();
|
||||
if (status != SD_OK) {
|
||||
SD_PowerOFF();
|
||||
SD_DeInit();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void sdcard_power_off(void) {
|
||||
SD_PowerOFF();
|
||||
SD_DeInit();
|
||||
}
|
||||
|
||||
uint64_t sdcard_get_capacity_in_bytes(void) {
|
||||
SD_CardInfo SDCardInfo;
|
||||
SD_GetCardInfo(&SDCardInfo);
|
||||
return SDCardInfo.CardCapacity;
|
||||
}
|
||||
|
||||
bool sdcard_read_block(uint8_t *dest, uint32_t block_num) {
|
||||
// TODO return error if not powered on
|
||||
|
||||
SD_Error status;
|
||||
|
||||
status = SD_ReadBlock(dest, block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE);
|
||||
if (status != SD_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SD_DMA_MODE
|
||||
// wait for DMA transfer to finish
|
||||
status = SD_WaitReadOperation();
|
||||
if (status != SD_OK) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// wait for SD controller to finish
|
||||
uint32_t stc = sys_tick_counter;
|
||||
while (SD_GetStatus() != SD_TRANSFER_OK) {
|
||||
if (sys_tick_has_passed(stc, 5000)) {
|
||||
//printf("[ERROR] timeout waiting for SD card read to finish\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sdcard_write_block(const uint8_t *src, uint32_t block_num) {
|
||||
// TODO return error if not powered on
|
||||
|
||||
SD_Error status;
|
||||
|
||||
status = SD_WriteBlock((uint8_t*)src, block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE);
|
||||
if (status != SD_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SD_DMA_MODE
|
||||
// wait for DMA transfer to finish
|
||||
status = SD_WaitReadOperation();
|
||||
if (status != SD_OK) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// wait for SD controller to finish
|
||||
uint32_t stc = sys_tick_counter;
|
||||
while (SD_GetStatus() != SD_TRANSFER_OK) {
|
||||
if (sys_tick_has_passed(stc, 5000)) {
|
||||
//printf("[ERROR] timeout waiting for SD card write to finish\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
static mp_obj_t sd_present(mp_obj_t self) {
|
||||
return MP_BOOL(sdcard_is_present());
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(sd_present_obj, sd_present);
|
||||
|
||||
static mp_obj_t sd_power(mp_obj_t self, mp_obj_t state) {
|
||||
bool result;
|
||||
if (mp_obj_is_true(state)) {
|
||||
result = sdcard_power_on();
|
||||
} else {
|
||||
sdcard_power_off();
|
||||
result = true;
|
||||
}
|
||||
return MP_BOOL(result);
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(sd_power_obj, sd_power);
|
||||
|
||||
static mp_obj_t sd_read(mp_obj_t self, mp_obj_t block_num) {
|
||||
uint8_t *dest = m_new(uint8_t, SDCARD_BLOCK_SIZE);
|
||||
if (!sdcard_read_block(dest, mp_obj_get_int(block_num))) {
|
||||
m_free(dest, SDCARD_BLOCK_SIZE);
|
||||
return mp_const_none;
|
||||
}
|
||||
return mp_obj_new_bytearray_by_ref(SDCARD_BLOCK_SIZE, dest);
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(sd_read_obj, sd_read);
|
||||
|
||||
STATIC const mp_map_elem_t sdcard_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_present), (mp_obj_t)&sd_present_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_power), (mp_obj_t)&sd_power_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&sd_read_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(sdcard_locals_dict, sdcard_locals_dict_table);
|
||||
|
||||
static const mp_obj_type_t sdcard_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_SDcard,
|
||||
.locals_dict = (mp_obj_t)&sdcard_locals_dict,
|
||||
};
|
||||
|
||||
const mp_obj_base_t pyb_sdcard_obj = {&sdcard_type};
|
12
stm/sdcard.h
12
stm/sdcard.h
@ -1,12 +0,0 @@
|
||||
// this is a fixed size and should not be changed
|
||||
#define SDCARD_BLOCK_SIZE (512)
|
||||
|
||||
void sdcard_init(void);
|
||||
bool sdcard_is_present(void);
|
||||
bool sdcard_power_on(void);
|
||||
void sdcard_power_off(void);
|
||||
uint64_t sdcard_get_capacity_in_bytes(void);
|
||||
bool sdcard_read_block(uint8_t *dest, uint32_t block_num);
|
||||
bool sdcard_write_block(const uint8_t *src, uint32_t block_num);
|
||||
|
||||
extern const struct _mp_obj_base_t pyb_sdcard_obj;
|
169
stm/servo.c
169
stm/servo.c
@ -1,169 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_rcc.h>
|
||||
#include <stm32f4xx_gpio.h>
|
||||
#include <stm32f4xx_tim.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "servo.h"
|
||||
|
||||
// PWM
|
||||
// TIM2 and TIM5 have CH1, CH2, CH3, CH4 on PA0-PA3 respectively
|
||||
// they are both 32-bit counters
|
||||
// 16-bit prescaler
|
||||
// TIM2_CH3 also on PB10 (used below)
|
||||
void servo_init(void) {
|
||||
// TIM2 clock enable
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
|
||||
|
||||
// for PB10
|
||||
/*
|
||||
// GPIOB Configuration: TIM2_CH3 (PB10)
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
// Connect TIM2 pins to AF1
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_TIM2);
|
||||
*/
|
||||
|
||||
// for PA0, PA1, PA2, PA3
|
||||
{
|
||||
// GPIOA Configuration: TIM2_CH0, TIM2_CH1 (PA0, PA1)
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
// Connect TIM2 pins to AF1
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2);
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM2);
|
||||
}
|
||||
|
||||
// Compute the prescaler value so TIM2 runs at 100kHz
|
||||
uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 100000) - 1;
|
||||
|
||||
// Time base configuration
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
TIM_TimeBaseStructure.TIM_Period = 2000; // timer cycles at 50Hz
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
|
||||
|
||||
// PWM Mode configuration
|
||||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
||||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
||||
TIM_OCInitStructure.TIM_Pulse = 150; // units of 10us
|
||||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
|
||||
TIM_OC1Init(TIM2, &TIM_OCInitStructure); // channel 1
|
||||
TIM_OC2Init(TIM2, &TIM_OCInitStructure); // channel 2
|
||||
TIM_OC3Init(TIM2, &TIM_OCInitStructure); // channel 3
|
||||
TIM_OC4Init(TIM2, &TIM_OCInitStructure); // channel 4
|
||||
|
||||
// ?
|
||||
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 1
|
||||
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 2
|
||||
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 3
|
||||
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 4
|
||||
|
||||
// ?
|
||||
TIM_ARRPreloadConfig(TIM2, ENABLE);
|
||||
|
||||
// TIM2 enable counter
|
||||
TIM_Cmd(TIM2, ENABLE);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
|
||||
STATIC mp_obj_t pyb_servo_set(mp_obj_t port, mp_obj_t value) {
|
||||
int p = mp_obj_get_int(port);
|
||||
int v = mp_obj_get_int(value);
|
||||
if (v < 50) { v = 50; }
|
||||
if (v > 250) { v = 250; }
|
||||
switch (p) {
|
||||
case 1: TIM2->CCR1 = v; break;
|
||||
case 2: TIM2->CCR2 = v; break;
|
||||
case 3: TIM2->CCR3 = v; break;
|
||||
case 4: TIM2->CCR4 = v; break;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(pyb_servo_set_obj, pyb_servo_set);
|
||||
|
||||
STATIC mp_obj_t pyb_pwm_set(mp_obj_t period, mp_obj_t pulse) {
|
||||
int pe = mp_obj_get_int(period);
|
||||
int pu = mp_obj_get_int(pulse);
|
||||
TIM2->ARR = pe;
|
||||
TIM2->CCR3 = pu;
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(pyb_pwm_set_obj, pyb_pwm_set);
|
||||
|
||||
typedef struct _pyb_servo_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint servo_id;
|
||||
} pyb_servo_obj_t;
|
||||
|
||||
STATIC void servo_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_servo_obj_t *self = self_in;
|
||||
print(env, "<Servo %lu>", self->servo_id);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t servo_obj_angle(mp_obj_t self_in, mp_obj_t angle) {
|
||||
pyb_servo_obj_t *self = self_in;
|
||||
#if MICROPY_ENABLE_FLOAT
|
||||
machine_int_t v = 152 + 85.0 * mp_obj_get_float(angle) / 90.0;
|
||||
#else
|
||||
machine_int_t v = 152 + 85 * mp_obj_get_int(angle) / 90;
|
||||
#endif
|
||||
if (v < 65) { v = 65; }
|
||||
if (v > 210) { v = 210; }
|
||||
switch (self->servo_id) {
|
||||
case 1: TIM2->CCR1 = v; break;
|
||||
case 2: TIM2->CCR2 = v; break;
|
||||
case 3: TIM2->CCR3 = v; break;
|
||||
case 4: TIM2->CCR4 = v; break;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(servo_obj_angle_obj, servo_obj_angle);
|
||||
|
||||
STATIC const mp_map_elem_t servo_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_angle), (mp_obj_t)&servo_obj_angle_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(servo_locals_dict, servo_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t servo_obj_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_Servo,
|
||||
.print = servo_obj_print,
|
||||
.locals_dict = (mp_obj_t)&servo_locals_dict,
|
||||
};
|
||||
|
||||
STATIC mp_obj_t pyb_Servo(mp_obj_t servo_id) {
|
||||
pyb_servo_obj_t *o = m_new_obj(pyb_servo_obj_t);
|
||||
o->base.type = &servo_obj_type;
|
||||
o->servo_id = mp_obj_get_int(servo_id);
|
||||
return o;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(pyb_Servo_obj, pyb_Servo);
|
@ -1,5 +0,0 @@
|
||||
void servo_init(void);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_servo_set_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_pwm_set_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_Servo_obj);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user