Ajout FishPeper
This commit is contained in:
129
OpenSky/arch/cc251x/cc251x.mk
Normal file
129
OpenSky/arch/cc251x/cc251x.mk
Normal file
@@ -0,0 +1,129 @@
|
||||
|
||||
CC = sdcc
|
||||
|
||||
HAL_SRCS := hal_led.c \
|
||||
hal_debug.c \
|
||||
hal_uart.c \
|
||||
hal_clocksource.c \
|
||||
hal_timeout.c \
|
||||
hal_wdt.c \
|
||||
hal_delay.c \
|
||||
hal_dma.c \
|
||||
hal_spi.c \
|
||||
hal_cc25xx.c \
|
||||
hal_io.c \
|
||||
hal_adc.c \
|
||||
hal_storage.c \
|
||||
hal_sbus.c \
|
||||
hal_ppm.c \
|
||||
hal_soft_serial.c
|
||||
|
||||
ARCH_SRCS := $(addprefix $(ARCH_DIR)/, $(HAL_SRCS))
|
||||
ARCH_HEADERS := $(ARCH_SRCS:.c=.h)
|
||||
|
||||
BOARD_SRCS := $(GENERIC_SRCS) \
|
||||
$(ARCH_SRCS)
|
||||
|
||||
INCLUDE_DIRS := $(INCLUDE_DIRS) \
|
||||
/usr/share/sdcc/include \
|
||||
$(SRC_DIR) \
|
||||
$(ARCH_DIR) \
|
||||
$(TARGET_DIR)
|
||||
|
||||
LDFLAGS_FLASH = --out-fmt-ihx \
|
||||
--code-loc 0x0c00 \
|
||||
--code-size $(FLASH_SIZE) \
|
||||
--xram-loc 0xf000 \
|
||||
--xram-size 0x300 \
|
||||
--iram-size 0x100
|
||||
|
||||
#programmer binary
|
||||
CC_TOOL ?= cc-tool
|
||||
|
||||
CFLAGS += --model-small \
|
||||
--opt-code-speed \
|
||||
$(addprefix -I,$(INCLUDE_DIRS))
|
||||
|
||||
ifdef DEBUG
|
||||
CFLAGS += --debug
|
||||
endif
|
||||
|
||||
HEADERS := $(BOARD_SRCS:.c=.h)
|
||||
ADB = $(BOARD_SRCS:.c=.adb)
|
||||
ASM = $(BOARD_SRCS:.c=.asm)
|
||||
LNK = $(BOARD_SRCS:.c=.lnk)
|
||||
LST = $(BOARD_SRCS:.c=.lst)
|
||||
REL = $(BOARD_SRCS:.c=.rel)
|
||||
RST = $(BOARD_SRCS:.c=.rst)
|
||||
SYM = $(BOARD_SRCS:.c=.sym)
|
||||
|
||||
#we build two flavours:
|
||||
# _full : includes the bootloader, use this for initial flashing
|
||||
# _update: just the opensky fw, relocated to be stored after the bootloader
|
||||
TARGET_FULL = $(OBJECT_DIR)/$(RESULT)_full.hex
|
||||
TARGET_UPDATE = $(OBJECT_DIR)/$(RESULT)_update.hex
|
||||
TARGET_NO_BL = $(OBJECT_DIR)/$(RESULT)_no_bl.hex
|
||||
BL_DIR = arch/cc251x/bootloader
|
||||
BL_HEX = bootloader.hex
|
||||
|
||||
PCDB = $(PROGS:.hex=.cdb)
|
||||
PLNK = $(PROGS:.hex=.lnk)
|
||||
PMAP = $(PROGS:.hex=.map)
|
||||
PMEM = $(PROGS:.hex=.mem)
|
||||
PAOM = $(PROGS:.hex=)
|
||||
|
||||
SREC_CAT_FOUND := $(shell command -v srec_cat 2> /dev/null)
|
||||
|
||||
TARGET_OBJS = $(addsuffix .rel,$(addprefix $(OBJECT_DIR)/$(TARGET)/,$(basename $(BOARD_SRCS))))
|
||||
TARGET_DEPS = $(addsuffix .d,$(addprefix $(OBJECT_DIR)/$(TARGET)/,$(basename $(BOARD_SRCS))))
|
||||
|
||||
# Search path for standard files
|
||||
#vpath %.c ./src
|
||||
#vpath %.c ./$(ARCH_DIR)
|
||||
|
||||
board: $(TARGET_UPDATE) $(TARGET_FULL)
|
||||
|
||||
bootloader:
|
||||
@echo "### Building bootloader ###"
|
||||
$(MAKE) -C $(BL_DIR) \
|
||||
STYLECHECK_DISABLED=1 \
|
||||
FLASH_SIZE=$(FLASH_SIZE) \
|
||||
CONFIG_INCLUDE_DIR=../../../$(TARGET_DIR) \
|
||||
clean all
|
||||
|
||||
$(TARGET_FULL): $(TARGET_UPDATE) bootloader
|
||||
@echo "merging bootloader and main code"
|
||||
ifndef SREC_CAT_FOUND
|
||||
$(error "could not find srec_cat binary. make sure to install the srecord package")
|
||||
else
|
||||
srec_cat -disable_sequence_warnings \
|
||||
$(TARGET_UPDATE) -intel \
|
||||
$(BL_DIR)/$(BL_HEX) -intel \
|
||||
-o $(TARGET_FULL) -intel
|
||||
@echo "done."
|
||||
endif
|
||||
|
||||
$(TARGET_UPDATE): $(TARGET_OBJS)
|
||||
$(V1) echo Linking: $(TARGET)
|
||||
$(V1) $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $@ $^
|
||||
|
||||
# this is just for development, DO NOT flash this for production
|
||||
$(TARGET_NO_BL): $(TARGET_OBJS)
|
||||
$(V1) $(CC) $(LDFLAGS_FLASH) $(CFLAGS) --code-loc 0x000 -o $@ $^
|
||||
|
||||
$(OBJECT_DIR)/$(TARGET)/%.rel: %.c
|
||||
$(V1) mkdir -p $(dir $@)
|
||||
$(V1) echo "%% $(notdir $<)" "$(STDOUT)" && \
|
||||
$(CC) -c -o $@ $(CFLAGS) $<
|
||||
|
||||
clean:
|
||||
$(V1) echo Cleaning: $(TARGET)
|
||||
$(V1) rm -f $(ADB) $(ASM) $(LNK) $(LST) $(TARGET_OBJS) $(RST) $(SYM)
|
||||
$(V1) rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
|
||||
$(V1) cd $(BL_DIR) && $(MAKE) clean
|
||||
|
||||
flash: $(OUTPUT_FULL)
|
||||
$(CC_TOOL) -f -e -w $(TARGET_FULL)
|
||||
|
||||
flash_no_bl: $(OUTPUT_NO_BL)
|
||||
$(CC_TOOL) -f -e -w $(TARGET_NO_BL)
|
||||
172
OpenSky/arch/cc251x/hal_adc.c
Normal file
172
OpenSky/arch/cc251x/hal_adc.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "hal_adc.h"
|
||||
#include "hal_defines.h"
|
||||
#include "hal_cc25xx.h"
|
||||
#include "portmacros.h"
|
||||
#include "config.h"
|
||||
#include "hal_dma.h"
|
||||
#include "debug.h"
|
||||
#include "delay.h"
|
||||
#include "wdt.h"
|
||||
|
||||
|
||||
// adc results
|
||||
__xdata uint16_t hal_adc_data[2];
|
||||
|
||||
void hal_adc_init(void) {
|
||||
hal_adc_data[0] = 0;
|
||||
hal_adc_data[1] = 0;
|
||||
|
||||
// pin config -> dir = input
|
||||
PORT2DIR(ADC_PORT) &= ~((1 << ADC1) | (1 << ADC0));
|
||||
|
||||
// set special function ADC for those pins:
|
||||
ADCCFG = (1 << ADC1) | (1 << ADC0);
|
||||
|
||||
// set up adc:
|
||||
// - external vref (avcc)
|
||||
// - 10bit adc
|
||||
// - stop on AIN7
|
||||
ADCCON2 = ADCCON2_SREF_AVDD | ADCCON2_SDIV_10BIT | ADCCON2_SCH_AIN7;
|
||||
|
||||
// full speed, start conversion (bit0+1 always write as 1...)
|
||||
ADCCON1 = ADCCON1_ST | ADCCON1_STSEL_FULL_SPEED | 0b11;
|
||||
|
||||
// configure DMA1 + DMA2:
|
||||
hal_adc_dma_init(1, &hal_adc_data[0], DMA_TRIG_ADC_CH0 + ADC0);
|
||||
hal_adc_dma_init(2, &hal_adc_data[1], DMA_TRIG_ADC_CH0 + ADC1);
|
||||
|
||||
// set pointer to the DMA configuration struct into DMA-channel 1-4
|
||||
// configuration
|
||||
SET_WORD(DMA1CFGH, DMA1CFGL, &hal_dma_config[1]);
|
||||
|
||||
hal_adc_dma_arm();
|
||||
|
||||
// for testing only, do not use under normal use
|
||||
#if ADC_DO_TEST
|
||||
adc_test();
|
||||
#endif // ADC_DO_TEST
|
||||
}
|
||||
|
||||
void hal_adc_dma_arm(void) {
|
||||
DMAARM = (DMA_ARM_CH1 | DMA_ARM_CH2);
|
||||
}
|
||||
|
||||
void hal_adc_process(void) {
|
||||
if (hal_adc_dma_done()) {
|
||||
// THIS OUTPUT BREAKS CONNECTIVITY! USE FOR DEBUGGING ONLY.
|
||||
// fine, arm dma:
|
||||
hal_adc_dma_arm();
|
||||
} else {
|
||||
// oops this should not happen
|
||||
debug_putc('D');
|
||||
// cancel and re arm dma
|
||||
// DMAARM = DMA_ARM_ABORT | (DMA_ARM_CH1 | DMA_ARM_CH2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void hal_adc_dma_init(uint8_t dma_id, uint16_t __xdata *dest_adr, uint8_t trig) {
|
||||
hal_dma_config[dma_id].PRIORITY = DMA_PRI_LOW; // example used high...
|
||||
hal_dma_config[dma_id].M8 = DMA_M8_USE_7_BITS;
|
||||
hal_dma_config[dma_id].IRQMASK = DMA_IRQMASK_DISABLE;
|
||||
hal_dma_config[dma_id].TRIG = trig;
|
||||
hal_dma_config[dma_id].TMODE = DMA_TMODE_BLOCK;
|
||||
hal_dma_config[dma_id].WORDSIZE = DMA_WORDSIZE_BYTE;
|
||||
|
||||
SET_WORD(hal_dma_config[dma_id].SRCADDRH, hal_dma_config[dma_id].SRCADDRL, &X_ADCL);
|
||||
SET_WORD(hal_dma_config[dma_id].DESTADDRH, hal_dma_config[dma_id].DESTADDRL, dest_adr);
|
||||
hal_dma_config[dma_id].VLEN = DMA_VLEN_USE_LEN;
|
||||
|
||||
SET_WORD(hal_dma_config[dma_id].LENH, hal_dma_config[dma_id].LENL, 2);
|
||||
hal_dma_config[dma_id].SRCINC = DMA_SRCINC_1;
|
||||
hal_dma_config[dma_id].DESTINC = DMA_DESTINC_1;
|
||||
}
|
||||
|
||||
uint8_t hal_adc_dma_done(void) {
|
||||
return ((DMAIRQ & (DMA_ARM_CH1 | DMA_ARM_CH2)) == (DMA_ARM_CH1 | DMA_ARM_CH2));
|
||||
}
|
||||
|
||||
uint8_t hal_adc_get_scaled(uint8_t ch) {
|
||||
uint16_t adc_data;
|
||||
// adc data is HHHHHHHHLLLL0000 -> shift >>6 to get 10bit
|
||||
// the cc2510 is _ALWAYS_ outputting data in two's complement format
|
||||
// thus we shift >>7 to get 9 bit two's complement
|
||||
// NOTE: the chip seems to have a bug, in contrast to the datasheet
|
||||
// measuring a signal close to GND seems to deliver negative values (!)
|
||||
// therefore we have to check for negative numbers and set them to zero
|
||||
if (ch == 0) {
|
||||
// convert to 8 bit (see above)
|
||||
adc_data = hal_adc_data[1] >> 7;
|
||||
if (adc_data & (1 << 8)) adc_data = 0; // bugfix: handle negative numbers
|
||||
// return fixed value
|
||||
return adc_data;
|
||||
} else {
|
||||
adc_data = hal_adc_data[0] >> 7;
|
||||
if (adc_data & (1 << 8)) adc_data = 0; // bugfix: handle negative numbers
|
||||
#ifdef ADC1_USE_ACS712
|
||||
// acs712 is connected to ADC1
|
||||
// when powered by 5V we can use a trick
|
||||
// to get a good resolution:
|
||||
// use inverted power inputs to get
|
||||
// 0A = 2.5V
|
||||
// 30A = 0.0V
|
||||
return 255-(adc_data);
|
||||
#else
|
||||
return adc_data;
|
||||
#endif // ADC1_USE_ACS712
|
||||
}
|
||||
}
|
||||
|
||||
#if ADC_DO_TEST
|
||||
void hal_adc_test(void) {
|
||||
debug("adc: running test\n"); debug_flush();
|
||||
|
||||
while (1) {
|
||||
debug("adc: re-arming adc\n"); debug_flush();
|
||||
hal_adc_dma_arm();
|
||||
|
||||
debug("adc: waiting for adc completion\n"); debug_flush();
|
||||
while (!hal_adc_dma_done()) {
|
||||
debug_putc('.');
|
||||
delay_ms(1);
|
||||
}
|
||||
debug("\nadc: done. res[0] = "); debug_flush();
|
||||
|
||||
debug_put_uint16(hal_adc_data[0]>>4);
|
||||
debug_putc('x'); debug_put_hex8(hal_adc_data[0]>>12);
|
||||
debug_put_hex8((hal_adc_data[0]>>4)&0xff);
|
||||
|
||||
debug(", res[1] = "); debug_flush();
|
||||
|
||||
debug_put_uint16(hal_adc_data[1]>>4);
|
||||
debug_putc('x'); debug_put_hex8(hal_adc_data[1]>>12);
|
||||
debug_put_hex8((hal_adc_data[1]>>4)&0xff);
|
||||
|
||||
debug_put_newline();
|
||||
|
||||
delay_ms(100);
|
||||
|
||||
// reset wdt
|
||||
wdt_reset();
|
||||
}
|
||||
}
|
||||
#endif // ADC_DO_TEST
|
||||
41
OpenSky/arch/cc251x/hal_adc.h
Normal file
41
OpenSky/arch/cc251x/hal_adc.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_ADC_H_
|
||||
#define HAL_ADC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef ADC_PORT
|
||||
#define ADC_ENABLED
|
||||
#endif // ADC_PORT
|
||||
|
||||
// adc results
|
||||
extern __xdata uint16_t hal_adc_data[2];
|
||||
|
||||
void hal_adc_init(void);
|
||||
uint8_t hal_adc_get_scaled(uint8_t ch);
|
||||
void hal_adc_dma_arm(void);
|
||||
void hal_adc_dma_init(uint8_t dma_id, uint16_t __xdata *dest_adr, uint8_t trig);
|
||||
uint8_t hal_adc_dma_done(void);
|
||||
|
||||
void hal_adc_test(void);
|
||||
void hal_adc_process(void);
|
||||
|
||||
#endif // HAL_ADC_H_
|
||||
231
OpenSky/arch/cc251x/hal_cc25xx.c
Normal file
231
OpenSky/arch/cc251x/hal_cc25xx.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "hal_cc25xx.h"
|
||||
#include "cc25xx.h"
|
||||
#include "hal_defines.h"
|
||||
#include "hal_dma.h"
|
||||
#include "delay.h"
|
||||
#include "timeout.h"
|
||||
#include "debug.h"
|
||||
#include "led.h"
|
||||
#include "frsky.h"
|
||||
#include <cc2510fx.h>
|
||||
|
||||
EXTERNAL_MEMORY volatile uint8_t hal_cc25xx_mode;
|
||||
|
||||
void hal_cc25xx_init(void) {
|
||||
// set highest prio for ch0 (RF)
|
||||
IP1 |= (1<<0);
|
||||
IP0 |= (1<<0);
|
||||
|
||||
|
||||
hal_cc25xx_mode = CC25XX_MODE_RX;
|
||||
|
||||
// if we support LNA/PA make sure to config the pin as output:
|
||||
#ifdef RF_LNA_PORT
|
||||
PORT2DIR(RF_LNA_PORT) |= (1 << RF_LNA_PIN);
|
||||
PORT2DIR(RF_PA_PORT) |= (1 << RF_PA_PIN);
|
||||
// set default to LNA active
|
||||
RF_PA_DISABLE();
|
||||
RF_LNA_ENABLE();
|
||||
#endif // RF_LNA_PORT
|
||||
|
||||
// if we support Diversity make sure to config the pin as output:
|
||||
#ifdef RF_ANTENNA_SWITCH_PORT
|
||||
PORT2DIR(RF_ANTENNA_SWITCH_PORT) |= (1 << RF_ANTENNA_SWITCH_PIN);
|
||||
// select first antenna
|
||||
RF_ANTENNA_SELECT_A();
|
||||
#endif // RF_ANTENNA_SWITCH_PORT
|
||||
|
||||
// if we support HIGH GAIN mode config pin as output:
|
||||
#ifdef RF_HIGH_GAIN_MODE_PORT
|
||||
PORT2DIR(RF_HIGH_GAIN_MODE_PORT) |= (1 << RF_HIGH_GAIN_MODE_PIN);
|
||||
// enable high gain mode?
|
||||
#ifdef RF_HIGH_GAIN_MODE_ENABLED
|
||||
RF_HIGH_GAIN_MODE_ENABLE();
|
||||
#else
|
||||
RF_HIGH_GAIN_MODE_DISABLE();
|
||||
#endif // RF_HIGH_GAIN_MODE_ENABLED
|
||||
#endif // RF_HIGH_GAIN_MODE_PORT
|
||||
|
||||
// if we support Bypass mode make sure to config the pin as output:
|
||||
#ifdef RF_BYPASS_PORT
|
||||
PORT2DIR(RF_BYPASS_MODE_PORT) |= (1 << RF_BYPASS_MODE_PIN);
|
||||
// set default to Bypass off
|
||||
#ifdef RF_BYPASS_MODE_ENABLED
|
||||
RF_BYPASS_MODE_ENABLE();
|
||||
#else
|
||||
RF_BYPASS_MODE_DISABLE();
|
||||
#endif // RF_BYPASS_MODE_ENABLED
|
||||
#endif // RF_BYPASS_PORT
|
||||
}
|
||||
|
||||
uint32_t hal_cc25xx_set_antenna(uint8_t id) {
|
||||
// select antenna 0 or 1:
|
||||
#ifdef RF_ANTENA_SWITCH_PORT
|
||||
if (id) {
|
||||
RF_ANTENNA_SELECT_B();
|
||||
} else {
|
||||
RF_ANTENNA_SELECT_A();
|
||||
}
|
||||
#endif // RF_ANTENNA_SWITCH_PORT
|
||||
return id;
|
||||
}
|
||||
|
||||
void hal_cc25xx_disable_rf_interrupt(void) {
|
||||
IEN2 &= ~(IEN2_RFIE);
|
||||
RFIM = 0;
|
||||
}
|
||||
|
||||
void hal_cc25xx_enter_rxmode(void) {
|
||||
#ifdef RF_LNA_PORT
|
||||
RF_LNA_ENABLE();
|
||||
delay_us(20);
|
||||
RF_PA_DISABLE();
|
||||
delay_us(5);
|
||||
#endif // RF_LNA_PORT
|
||||
|
||||
// set up dma for radio--->buffer
|
||||
hal_cc25xx_setup_rf_dma(CC25XX_MODE_RX);
|
||||
|
||||
// configure interrupt for every received packet
|
||||
IEN2 |= (IEN2_RFIE);
|
||||
|
||||
// mask done irq
|
||||
RFIM = (1<<4);
|
||||
// interrupts should be enabled globally already..
|
||||
// skip this! sei();
|
||||
}
|
||||
|
||||
void hal_cc25xx_enter_txmode(void) {
|
||||
#ifdef RF_LNA_PORT
|
||||
RF_LNA_DISABLE();
|
||||
delay_us(20);
|
||||
RF_PA_ENABLE();
|
||||
delay_us(5);
|
||||
#endif // RF_LNA_PORT
|
||||
|
||||
// abort ch0
|
||||
DMAARM = DMA_ARM_ABORT | DMA_ARM_CH0;
|
||||
hal_cc25xx_setup_rf_dma(CC25XX_MODE_TX);
|
||||
}
|
||||
|
||||
void hal_cc25xx_setup_rf_dma(uint8_t mode) {
|
||||
// CPU has priority over DMA
|
||||
// Use 8 bits for transfer count
|
||||
// No DMA interrupt when done
|
||||
// DMA triggers on radio
|
||||
// Single transfer per trigger.
|
||||
// One byte is transferred each time.
|
||||
|
||||
hal_dma_config[0].PRIORITY = DMA_PRI_HIGH;
|
||||
hal_dma_config[0].M8 = DMA_M8_USE_8_BITS;
|
||||
hal_dma_config[0].IRQMASK = DMA_IRQMASK_DISABLE;
|
||||
hal_dma_config[0].TRIG = DMA_TRIG_RADIO;
|
||||
hal_dma_config[0].TMODE = DMA_TMODE_SINGLE;
|
||||
hal_dma_config[0].WORDSIZE = DMA_WORDSIZE_BYTE;
|
||||
|
||||
// store mode
|
||||
hal_cc25xx_mode = mode;
|
||||
|
||||
if (hal_cc25xx_mode == CC25XX_MODE_TX) {
|
||||
// Transmitter specific DMA settings
|
||||
// Source: radioPktBuffer
|
||||
// Destination: RFD register
|
||||
// Use the first byte read + 1
|
||||
// Sets the maximum transfer count allowed (length byte + data)
|
||||
// Data source address is incremented by 1 byte
|
||||
// Destination address is constant
|
||||
SET_WORD(hal_dma_config[0].SRCADDRH, hal_dma_config[0].SRCADDRL, frsky_packet_buffer);
|
||||
SET_WORD(hal_dma_config[0].DESTADDRH, hal_dma_config[0].DESTADDRL, &X_RFD);
|
||||
hal_dma_config[0].VLEN = DMA_VLEN_FIRST_BYTE_P_1;
|
||||
SET_WORD(hal_dma_config[0].LENH, hal_dma_config[0].LENL, (FRSKY_PACKET_LENGTH+1));
|
||||
hal_dma_config[0].SRCINC = DMA_SRCINC_1;
|
||||
hal_dma_config[0].DESTINC = DMA_DESTINC_0;
|
||||
} else {
|
||||
// Receiver specific DMA settings:
|
||||
// Source: RFD register
|
||||
// Destination: radioPktBuffer
|
||||
// Use the first byte read + 3 (incl. 2 status bytes)
|
||||
// Sets maximum transfer count allowed (length byte + data + 2 status bytes)
|
||||
// Data source address is constant
|
||||
// Destination address is incremented by 1 byte for each write
|
||||
SET_WORD(hal_dma_config[0].SRCADDRH, hal_dma_config[0].SRCADDRL, &X_RFD);
|
||||
SET_WORD(hal_dma_config[0].DESTADDRH, hal_dma_config[0].DESTADDRL, frsky_packet_buffer);
|
||||
hal_dma_config[0].VLEN = DMA_VLEN_FIRST_BYTE_P_3;
|
||||
SET_WORD(hal_dma_config[0].LENH, hal_dma_config[0].LENL, (FRSKY_PACKET_LENGTH+3));
|
||||
hal_dma_config[0].SRCINC = DMA_SRCINC_0;
|
||||
hal_dma_config[0].DESTINC = DMA_DESTINC_1;
|
||||
}
|
||||
|
||||
// Save pointer to the DMA configuration struct into DMA-channel 0
|
||||
// configuration registers
|
||||
SET_WORD(DMA0CFGH, DMA0CFGL, &hal_dma_config[0]);
|
||||
|
||||
// frsky_packet_received = 0;
|
||||
}
|
||||
|
||||
void hal_cc25xx_enable_receive(void) {
|
||||
// start receiving on dma channel 0
|
||||
DMAARM = DMA_ARM_CH0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void hal_cc25xx_rf_interrupt(void) __interrupt RF_VECTOR {
|
||||
// clear int flag
|
||||
RFIF &= ~(1<<4);
|
||||
|
||||
// clear general statistics reg
|
||||
S1CON &= ~0x03;
|
||||
|
||||
if (hal_cc25xx_mode == CC25XX_MODE_RX) {
|
||||
// mark as received:
|
||||
frsky_packet_received = 1;
|
||||
// re arm DMA channel 0
|
||||
hal_cc25xx_enable_receive();
|
||||
} else {
|
||||
frsky_packet_sent = 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t hal_cc25xx_transmission_completed(void) {
|
||||
// this flag is set in the RF isr
|
||||
return (frsky_packet_sent);
|
||||
}
|
||||
|
||||
|
||||
void hal_cc25xx_transmit_packet(volatile uint8_t *buffer, uint8_t len) {
|
||||
UNUSED(buffer);
|
||||
UNUSED(len);
|
||||
|
||||
RFST = RFST_STX;
|
||||
|
||||
// start transmitting on dma channel 0
|
||||
DMAARM = DMA_ARM_CH0;
|
||||
|
||||
// mark packet as not sent (will be modified in RF isr):
|
||||
frsky_packet_sent = 0;
|
||||
|
||||
// tricky: this will force an int request and
|
||||
// initiate the actual transmission
|
||||
S1CON |= 0x03;
|
||||
}
|
||||
|
||||
276
OpenSky/arch/cc251x/hal_cc25xx.h
Normal file
276
OpenSky/arch/cc251x/hal_cc25xx.h
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_CC25XX_H_
|
||||
#define HAL_CC25XX_H_
|
||||
#include <stdint.h>
|
||||
#include "hal_defines.h"
|
||||
#include "config.h"
|
||||
#include <cc2510fx.h>
|
||||
|
||||
|
||||
#define CC25XX_FIFO FIFO
|
||||
|
||||
#define hal_cc25xx_set_register(reg, val) { reg = val; }
|
||||
#define hal_cc25xx_strobe(val) { RFST = val; }
|
||||
#define hal_cc25xx_get_register(r) (r)
|
||||
#define hal_cc25xx_get_register_burst(r) (r)
|
||||
|
||||
|
||||
#ifdef RF_LNA_PORT
|
||||
#define RF_LNA_ENABLE() { PORT2BIT(RF_LNA_PORT, RF_LNA_PIN) = RF_LNA_ON_LEVEL; }
|
||||
#define RF_LNA_DISABLE() { PORT2BIT(RF_LNA_PORT, RF_LNA_PIN) = ~RF_LNA_ON_LEVEL; }
|
||||
#define RF_PA_ENABLE() { PORT2BIT(RF_PA_PORT, RF_PA_PIN) = RF_PA_ON_LEVEL; }
|
||||
#define RF_PA_DISABLE() { PORT2BIT(RF_PA_PORT, RF_PA_PIN) = ~RF_PA_ON_LEVEL; }
|
||||
#endif // RF_LNA_PORT
|
||||
|
||||
#ifdef RF_ANTENNA_SWITCH_PORT
|
||||
#define RF_ANTENNA_SELECT_A() { PORT2BIT(RF_ANTENNA_SWITCH_PORT, RF_ANTENNA_SWITCH_PIN) = RF_ANTENNA_A_LEVEL; }
|
||||
#define RF_ANTENNA_SELECT_B() { PORT2BIT(RF_ANTENNA_SWITCH_PORT, RF_ANTENNA_SWITCH_PIN) = ~RF_ANTENNA_A_LEVEL; }
|
||||
#endif // RF_ANTENNA_SWITCH_PORT
|
||||
|
||||
#ifdef RF_HIGH_GAIN_MODE_PORT
|
||||
#define RF_HIGH_GAIN_MODE_ENABLE() { \
|
||||
PORT2BIT(RF_HIGH_GAIN_MODE_PORT, RF_HIGH_GAIN_MODE_PIN) = RF_HIGH_GAIN_MODE_ON_LEVEL; }
|
||||
#define RF_HIGH_GAIN_MODE_DISBALE() { \
|
||||
PORT2BIT(RF_HIGH_GAIN_MODE_PORT, RF_HIGH_GAIN_MODE_PIN) = ~RF_HIGH_GAIN_MODE_ON_LEVEL; }
|
||||
#endif // RF_HIGH_GAIN_MODE_PORT
|
||||
|
||||
#ifdef RF_BYPASS_MODE_PORT
|
||||
#define RF_BYPASS_MODE_ENABLE() { PORT2BIT(RF_BYPASS_MODE_PORT, RF_BYPASS_MODE_PIN) = RF_BYPASS_MODE_ON_LEVEL; }
|
||||
#define RF_BYPASS_MODE_DISABLE() { PORT2BIT(RF_BYPASS_MODE_PORT, RF_BYPASS_MODE_PIN) = ~RF_BYPASS_MODE_ON_LEVEL; }
|
||||
#endif // RF_BYPASS_MODE_PORT
|
||||
|
||||
uint32_t hal_cc25xx_set_antenna(uint8_t id);
|
||||
#define hal_cc25xx_process_packet(packet_received, buffer, maxlen) {}
|
||||
|
||||
void hal_cc25xx_init(void);
|
||||
#define hal_cc25xx_set_gdo_mode() {}
|
||||
void hal_cc25xx_disable_rf_interrupt(void);
|
||||
|
||||
#define hal_cc25xx_rx_sleep() { delay_us(1000); }
|
||||
#define hal_cc25xx_tx_sleep() { delay_us(900); }
|
||||
|
||||
void hal_cc25xx_enter_rxmode(void);
|
||||
void hal_cc25xx_enter_txmode(void);
|
||||
void hal_cc25xx_setup_rf_dma(uint8_t mode);
|
||||
void hal_cc25xx_enable_receive(void);
|
||||
void hal_cc25xx_transmit_packet(volatile uint8_t *buffer, uint8_t len);
|
||||
uint8_t hal_cc25xx_transmission_completed(void);
|
||||
|
||||
void hal_cc25xx_rf_interrupt(void) __interrupt RF_VECTOR;
|
||||
|
||||
#define hal_cc25xx_partnum_valid(p, v) ((p == 0x81) && (v = 0x04))
|
||||
|
||||
#define PERCFG_U0CFG (1<<0)
|
||||
#define PERCFG_U1CFG (1<<1)
|
||||
#define PERCFG_T4CFG (1<<4)
|
||||
#define PERCFG_T3CFG (1<<5)
|
||||
#define PERCFG_T1CFG (1<<6)
|
||||
|
||||
#define IEN0_RFTXRXIE (1<<0)
|
||||
#define IEN0_ADCIE (1<<1)
|
||||
#define IEN0_URX0IE (1<<2)
|
||||
#define IEN0_URX1IE (1<<3)
|
||||
#define IEN0_ENCIE (1<<4)
|
||||
#define IEN0_STIE (1<<5)
|
||||
#define IEN0_EA (1<<7)
|
||||
|
||||
// bit 7 - unused
|
||||
// bit 6 - unused
|
||||
#define PICTL_P2IEN (1<<5)
|
||||
#define PICTL_P0IENH (1<<4)
|
||||
#define PICTL_P0IENL (1<<3)
|
||||
#define PICTL_P2ICON (1<<2)
|
||||
#define PICTL_P1ICON (1<<1)
|
||||
#define PICTL_P0ICON (1<<0)
|
||||
|
||||
#define IEN1_P0IE (1<<5)
|
||||
#define IEN1_T4IE (1<<4)
|
||||
#define IEN1_T3IE (1<<3)
|
||||
#define IEN1_T2IE (1<<2)
|
||||
#define IEN1_T1IE (1<<1)
|
||||
#define IEN1_DMAIE (1<<0)
|
||||
|
||||
#define IEN2_RFIE (1<<0)
|
||||
#define IEN2_P2IE (1<<1)
|
||||
#define IEN2_UTX0IE (1<<2)
|
||||
#define IEN2_UTX1IE (1<<3)
|
||||
#define IEN2_P1IE (1<<4)
|
||||
#define IEN2_WDTIE (1<<5)
|
||||
|
||||
#define U0GCR_ORDER (1<<5)
|
||||
#define U0GCR_CPHA (1<<6)
|
||||
#define U0GCR_CPOL (1<<7)
|
||||
#define U0CSR_TX_BYTE (1<<1)
|
||||
|
||||
#define U1GCR_ORDER (1<<5)
|
||||
#define U1GCR_CPHA (1<<6)
|
||||
#define U1GCR_CPOL (1<<7)
|
||||
|
||||
#define UxCSR_RX_ENABLE (1<<6)
|
||||
#define UxCSR_RX_BYTE (1<<2)
|
||||
#define UxCSR_TX_BYTE (1<<1)
|
||||
|
||||
|
||||
#define RFST_SNOP 0x05
|
||||
#define RFST_SIDLE 0x04
|
||||
#define RFST_STX 0x03
|
||||
#define RFST_SRX 0x02
|
||||
#define RFST_SCAL 0x01
|
||||
#define RFST_SFSTXON 0x00
|
||||
// statemachine on cc2510 is different.
|
||||
// instead of SF*X we should use SIDLE
|
||||
#define RFST_SFTX RFST_SIDLE
|
||||
#define RFST_SFRX RFST_SIDLE
|
||||
|
||||
// append status
|
||||
#define CC2500_PKTCTRL1_APPEND_STATUS (1<<2)
|
||||
// crc autoflush
|
||||
#define CC2500_PKTCTRL1_CRC_AUTOFLUSH (1<<3)
|
||||
// adress checks
|
||||
#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_00 ((0<<1) | (0<<0))
|
||||
#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_01 ((0<<1) | (1<<0))
|
||||
#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_10 ((1<<1) | (0<<0))
|
||||
#define CC2500_PKTCTRL1_FLAG_ADR_CHECK_11 ((1<<1) | (1<<0))
|
||||
|
||||
|
||||
#define CLKCON_TICKSPD_001 (0b00001000)
|
||||
#define CLKCON_TICKSPD_010 (0b00010000)
|
||||
#define CLKCON_TICKSPD_011 (0b00011000)
|
||||
#define CLKCON_TICKSPD_100 (0b00100000)
|
||||
#define CLKCON_TICKSPD_101 (0b00101000)
|
||||
#define CLKCON_TICKSPD_110 (0b00110000)
|
||||
#define CLKCON_TICKSPD_111 (0b00111000)
|
||||
#define CLKCON_OSC32K (1<<7)
|
||||
|
||||
#define ADCCON2_SREF_INT (0b00<<6)
|
||||
#define ADCCON2_SREF_EXT (0b01<<6)
|
||||
#define ADCCON2_SREF_AVDD (0b10<<6)
|
||||
#define ADCCON2_SREF_EXTDIFF (0b11<<6)
|
||||
#define ADCCON2_SDIV_7BIT (0b00<<4)
|
||||
#define ADCCON2_SDIV_9BIT (0b01<<4)
|
||||
#define ADCCON2_SDIV_10BIT (0b10<<4)
|
||||
#define ADCCON2_SDIV_12BIT (0b11<<4)
|
||||
#define ADCCON2_SCH_AIN0 (0b0000<<0)
|
||||
#define ADCCON2_SCH_AIN1 (0b0001<<0)
|
||||
#define ADCCON2_SCH_AIN2 (0b0010<<0)
|
||||
#define ADCCON2_SCH_AIN3 (0b0011<<0)
|
||||
#define ADCCON2_SCH_AIN4 (0b0100<<0)
|
||||
#define ADCCON2_SCH_AIN5 (0b0101<<0)
|
||||
#define ADCCON2_SCH_AIN6 (0b0110<<0)
|
||||
#define ADCCON2_SCH_AIN7 (0b0111<<0)
|
||||
#define ADCCON2_SCH_AIN0AIN1 (0b1000<<0)
|
||||
#define ADCCON2_SCH_AIN2AIN3 (0b1001<<0)
|
||||
#define ADCCON2_SCH_AIN4AIN5 (0b1010<<0)
|
||||
#define ADCCON2_SCH_AIN6AIN7 (0b1011<<0)
|
||||
#define ADCCON2_SCH_GND (0b1100<<0)
|
||||
#define ADCCON2_SCH_POSVREF (0b1101<<0)
|
||||
#define ADCCON2_SCH_TEMP (0b1110<<0)
|
||||
#define ADCCON2_SCH_VDD3 (0b1111<<0)
|
||||
|
||||
#define ADCCON1_ST (1<<6)
|
||||
#define ADCCON1_STSEL_FULL_SPEED (0b01<<4)
|
||||
|
||||
#define WDCTL_EN (1<<3)
|
||||
#define WDCTL_MODE (1<<2)
|
||||
#define WDCTL_INT (0b11)
|
||||
#define WDCTL_INT_1S (0b00)
|
||||
|
||||
#define FCTL_BUSY (1<<7)
|
||||
#define FCTL_SWBUSY (1<<6)
|
||||
#define FCTL_WRITE (1<<1)
|
||||
#define FCTL_ERASE (1<<0)
|
||||
|
||||
|
||||
#define T1CTL_MODE_SUSPEND (0b00<<0)
|
||||
#define T1CTL_MODE_FREE_RUNNING (0b01<<0)
|
||||
#define T1CTL_MODE_MODULO (0b10<<0)
|
||||
#define T1CTL_MODE_UPDOWN (0b11<<0)
|
||||
#define T1CTL_DIV_1 (0b00<<2)
|
||||
#define T1CTL_DIV_8 (0b01<<2)
|
||||
#define T1CTL_DIV_32 (0b10<<2)
|
||||
#define T1CTL_DIV_128 (0b11<<2)
|
||||
#define T1CTL_OVFIF (1<<4)
|
||||
#define T1CTL_CH0_IF (1<<5)
|
||||
#define T1CTL_CH1_IF (1<<6)
|
||||
#define T1CTL_CH2_IF (1<<7)
|
||||
|
||||
|
||||
|
||||
#define T3CTL_MODE_SUSPEND (0b00<<0)
|
||||
#define T3CTL_MODE_FREE_RUNNING (0b01<<0)
|
||||
#define T3CTL_MODE_MODULO (0b10<<0)
|
||||
#define T3CTL_MODE_UPDOWN (0b11<<0)
|
||||
#define T3CTL_CLR (1<<2)
|
||||
#define T3CTL_OVFIM (1<<3)
|
||||
#define T3CTL_START (1<<4)
|
||||
#define T3CTL_DIV_1 (0b000<<5)
|
||||
#define T3CTL_DIV_2 (0b001<<5)
|
||||
#define T3CTL_DIV_4 (0b010<<5)
|
||||
#define T3CTL_DIV_8 (0b011<<5)
|
||||
#define T3CTL_DIV_16 (0b100<<5)
|
||||
#define T3CTL_DIV_32 (0b101<<5)
|
||||
#define T3CTL_DIV_64 (0b110<<5)
|
||||
#define T3CTL_DIV_128 (0b111<<5)
|
||||
|
||||
|
||||
#define T4CTL_MODE_SUSPEND (0b00<<0)
|
||||
#define T4CTL_MODE_FREE_RUNNING (0b01<<0)
|
||||
#define T4CTL_MODE_MODULO (0b10<<0)
|
||||
#define T4CTL_MODE_UPDOWN (0b11<<0)
|
||||
#define T4CTL_CLR (1<<2)
|
||||
#define T4CTL_OVFIM (1<<3)
|
||||
#define T4CTL_START (1<<4)
|
||||
#define T4CTL_DIV_1 (0b000<<5)
|
||||
#define T4CTL_DIV_2 (0b001<<5)
|
||||
#define T4CTL_DIV_4 (0b010<<5)
|
||||
#define T4CTL_DIV_8 (0b011<<5)
|
||||
#define T4CTL_DIV_16 (0b100<<5)
|
||||
#define T4CTL_DIV_32 (0b101<<5)
|
||||
#define T4CTL_DIV_64 (0b110<<5)
|
||||
#define T4CTL_DIV_128 (0b111<<5)
|
||||
|
||||
|
||||
#define T1CCTLx_CAP_NO (0b00<<0)
|
||||
#define T1CCTLx_CAP_RISING (0b01<<0)
|
||||
#define T1CCTLx_CAP_FALLING (0b10<<0)
|
||||
#define T1CCTLx_CAP_BOTH (0b11<<0)
|
||||
#define T1CCTLx_MODE_CAPTURE (0<<2)
|
||||
#define T1CCTLx_MODE_COMPARE (1<<2)
|
||||
#define T1CCTLx_CMP_SET (0b000<<3)
|
||||
#define T1CCTLx_CMP_CLEAR (0b001<<3)
|
||||
#define T1CCTLx_CMP_TOGGLE (0b010<<3)
|
||||
#define T1CCTLx_CMP_SETCLR0 (0b011<<3)
|
||||
#define T1CCTLx_CMP_CLRSET0 (0b100<<3)
|
||||
#define T1CCTLx_CMP_RES0 (0b101<<3)
|
||||
#define T1CCTLx_CMP_RES1 (0b110<<3)
|
||||
#define T1CCTLx_CMP_RES2 (0b111<<3)
|
||||
#define T1CCTLx_IM (1<<6)
|
||||
#define T1CCTLx_CPSEL_RF (1<<7)
|
||||
|
||||
|
||||
// add missing defines
|
||||
#include <compiler.h>
|
||||
SFRX(TEST2, 0xDF23);
|
||||
SFRX(TEST1, 0xDF24);
|
||||
SFRX(TEST0, 0xDF25);
|
||||
|
||||
|
||||
#endif // HAL_CC25XX_H_
|
||||
50
OpenSky/arch/cc251x/hal_clocksource.c
Normal file
50
OpenSky/arch/cc251x/hal_clocksource.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "hal_clocksource.h"
|
||||
#include "hal_cc25xx.h"
|
||||
#include "led.h"
|
||||
|
||||
void hal_clocksource_init(void) {
|
||||
// for debugging clocksource problems
|
||||
led_red_on();
|
||||
led_green_on();
|
||||
|
||||
// power up osc (?)
|
||||
SLEEP &= ~CLOCKSOURCE_OSC_PD_BIT;
|
||||
// wait for XOSC stable
|
||||
while (!CLOCKSOURCE_XOSC_STABLE()) {}
|
||||
NOP();
|
||||
|
||||
// start crystal osc as HS clocksource, OSC32 is int rc osc
|
||||
CLKCON = 0x80;
|
||||
|
||||
// wait for selection to be active
|
||||
while (!CLOCKSOURCE_XOSC_STABLE()) {}
|
||||
NOP();
|
||||
|
||||
// power down the unused oscillator
|
||||
SLEEP |= CLOCKSOURCE_OSC_PD_BIT;
|
||||
|
||||
|
||||
// for debugging clocksource problems
|
||||
led_red_off();
|
||||
led_green_off();
|
||||
}
|
||||
|
||||
47
OpenSky/arch/cc251x/hal_clocksource.h
Normal file
47
OpenSky/arch/cc251x/hal_clocksource.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_CLOCKSOURCE_H_
|
||||
#define HAL_CLOCKSOURCE_H_
|
||||
|
||||
#include "hal_cc25xx.h"
|
||||
|
||||
void hal_clocksource_init(void);
|
||||
|
||||
// bit mask used to check the stability of XOSC
|
||||
#define CLOCKSOURCE_XOSC_STABLE_BIT 0x40
|
||||
// bit mak used to check the stability of the High-frequency RC oscillator
|
||||
#define CLOCKSOURCE_HFRC_STB_BIT 0x20
|
||||
// bit maks used to power down system clock oscillators
|
||||
#define CLOCKSOURCE_OSC_PD_BIT 0x04
|
||||
|
||||
// bit mask used to control the system clock oscillator
|
||||
#define CLOCKSOURCE_MAIN_OSC_BITS 0x7F
|
||||
|
||||
// bit mask used to select/check the system clock oscillator
|
||||
#define CLOCKSOURCE_OSC_BIT 0x40
|
||||
|
||||
// macros to check for stable oscs:
|
||||
#define CLOCKSOURCE_HFRC_OSC_STABLE() (SLEEP & (CLOCKSOURCE_HFRC_STB_BIT))
|
||||
#define CLOCKSOURCE_XOSC_STABLE() (SLEEP & (CLOCKSOURCE_XOSC_STABLE_BIT))
|
||||
|
||||
#define CLOCKSOURCE_XOSC 0
|
||||
#define CLOCKSOURCE_HFRC 1
|
||||
|
||||
#endif // HAL_CLOCKSOURCE_H_
|
||||
160
OpenSky/arch/cc251x/hal_debug.c
Normal file
160
OpenSky/arch/cc251x/hal_debug.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "hal_debug.h"
|
||||
#include "hal_defines.h"
|
||||
|
||||
void hal_debug_init(void) {
|
||||
__xdata union hal_uart_config_t uart_config;
|
||||
|
||||
#ifndef DEBUG_UART
|
||||
#error "ERROR: DEBUG_UART not defined"
|
||||
#endif // DEBUG_UART
|
||||
|
||||
#if DEBUG_UART == USART0_P0
|
||||
// USART0 use ALT1 -> Clear flag -> Port P0_3 = TX
|
||||
PERCFG &= ~(PERCFG_U0CFG);
|
||||
|
||||
// configure pin P0_3 (TX) as special function:
|
||||
P0SEL |= (1<<3);
|
||||
// set P0_5 as normal IO
|
||||
P1SEL &= ~(1<<5);
|
||||
|
||||
// make tx pin output:
|
||||
P0DIR |= (1<<3);
|
||||
#elif DEBUG_UART == USART0_P1
|
||||
// USART0 use ALT2 -> Set flag -> Port P1_5 = TX
|
||||
PERCFG |= (PERCFG_U0CFG);
|
||||
|
||||
// configure pin P1_5 (TX) as special function
|
||||
P1SEL |= (1<<5);
|
||||
// set P0_3 as normal IO
|
||||
P0SEL &= ~(1<<3);
|
||||
|
||||
// make tx pin output:
|
||||
P1DIR |= (1<<5);
|
||||
#elif DEBUG_UART == USART1_P0
|
||||
// USART1 use ALT1 -> Clear flag -> Port P0_4 = TX
|
||||
PERCFG &= ~(PERCFG_U1CFG);
|
||||
|
||||
// USART1 has priority when USART0 is also enabled
|
||||
P2DIR = (P2DIR & 0x3F) | 0b01000000;
|
||||
|
||||
// configure pin P0_4 special function:
|
||||
P0SEL |= (1<<4);
|
||||
// configure P1_6 as normal IO
|
||||
P1SEL &= ~(1<<6);
|
||||
|
||||
// make sure all P1 pins switch to normal GPIO
|
||||
// P1SEL &= ~(0xF0);
|
||||
|
||||
// make tx pin output:
|
||||
P0DIR |= (1<<4);
|
||||
#else
|
||||
#error "ERROR: UNSUPPORTED DEBUG UART"
|
||||
#endif // DEBUG_UART == ...
|
||||
|
||||
// this assumes cpu runs from XOSC (26mhz) !
|
||||
// set baudrate
|
||||
#if (DEBUG_UART == USART0_P0) || (DEBUG_UART == USART0_P1)
|
||||
U0BAUD = CC2510_BAUD_M_115200;
|
||||
U0GCR = (U0GCR & ~0x1F) | (CC2510_BAUD_E_115200);
|
||||
#else
|
||||
U1BAUD = CC2510_BAUD_M_115200;
|
||||
U1GCR = (U1GCR & ~0x1F) | (CC2510_BAUD_E_115200);
|
||||
#endif // DEBUG_UART == ...
|
||||
|
||||
// set up config
|
||||
uart_config.bit.START = 0; // startbit level = low
|
||||
uart_config.bit.STOP = 1; // stopbit level = high
|
||||
uart_config.bit.SPB = 0; // 1 stopbit
|
||||
uart_config.bit.PARITY = 0; // no parity
|
||||
uart_config.bit.BIT9 = 0; // 8bit
|
||||
uart_config.bit.D9 = 0; // 8 Bits
|
||||
uart_config.bit.FLOW = 0; // no hw flow control
|
||||
uart_config.bit.ORDER = 0; // lsb first
|
||||
hal_debug_set_mode(&uart_config);
|
||||
|
||||
// enable interrupts:
|
||||
sei();
|
||||
}
|
||||
|
||||
static void hal_debug_set_mode(EXTERNAL_MEMORY union hal_uart_config_t *cfg) {
|
||||
#if (DEBUG_UART == USART0_P0) || (DEBUG_UART == USART0_P1)
|
||||
// enable uart mode
|
||||
U0CSR |= 0x80;
|
||||
|
||||
// store config to UxUCR register
|
||||
U0UCR = cfg->byte & (0x7F);
|
||||
|
||||
// store config to U1GCR: (msb/lsb)
|
||||
if (cfg->bit.ORDER) {
|
||||
U0GCR |= U0GCR_ORDER;
|
||||
} else {
|
||||
U0GCR &= ~U0GCR_ORDER;
|
||||
}
|
||||
|
||||
// interrupt prio to 0 (0..3=highest)
|
||||
IP0 &= ~(1<<2);
|
||||
IP1 &= ~(1<<2);
|
||||
#else
|
||||
// enable uart mode
|
||||
U1CSR |= 0x80;
|
||||
|
||||
// store config to UxUCR register
|
||||
U1UCR = cfg->byte & (0x7F);
|
||||
|
||||
// store config to U1GCR: (msb/lsb)
|
||||
if (cfg->bit.ORDER) {
|
||||
U1GCR |= U1GCR_ORDER;
|
||||
} else {
|
||||
U1GCR &= ~U1GCR_ORDER;
|
||||
}
|
||||
// interrupt prio to 0 (0..3=highest)
|
||||
IP0 &= ~(1<<3);
|
||||
IP1 &= ~(1<<3);
|
||||
#endif // DEBUG_UART == ...
|
||||
}
|
||||
|
||||
|
||||
void hal_debug_start_transmission(uint8_t ch) {
|
||||
#if (DEBUG_UART == USART0_P0) || (DEBUG_UART == USART0_P1)
|
||||
// clear flags
|
||||
UTX0IF = 0;
|
||||
U0CSR &= ~UxCSR_TX_BYTE;
|
||||
|
||||
// enable TX int:
|
||||
IEN2 |= (IEN2_UTX0IE);
|
||||
|
||||
// send this char
|
||||
U0DBUF = ch;
|
||||
#else
|
||||
// clear flags
|
||||
UTX1IF = 0;
|
||||
U1CSR &= ~UxCSR_TX_BYTE;
|
||||
|
||||
// enable TX int:
|
||||
IEN2 |= (IEN2_UTX1IE);
|
||||
|
||||
// send this char
|
||||
U1DBUF = ch;
|
||||
#endif // DEBUG_UART == ...
|
||||
}
|
||||
|
||||
|
||||
53
OpenSky/arch/cc251x/hal_debug.h
Normal file
53
OpenSky/arch/cc251x/hal_debug.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_DEBUG_H_
|
||||
#define HAL_DEBUG_H_
|
||||
|
||||
#include "hal_cc25xx.h"
|
||||
#include "hal_uart.h"
|
||||
#include <stdint.h>
|
||||
|
||||
void hal_debug_init(void);
|
||||
void hal_debug_start_transmission(uint8_t ch);
|
||||
|
||||
#if (DEBUG_UART == USART0_P0) || (DEBUG_UART == USART0_P1)
|
||||
#define hal_debug_int_enabled() (IEN2 & (IEN2_UTX0IE))
|
||||
#else
|
||||
#define hal_debug_int_enabled() (IEN2 & (IEN2_UTX1IE))
|
||||
#endif // DEBUG_UART == ...
|
||||
#define hal_debug_int_enable() { sei(); }
|
||||
#define hal_debug_int_disable() { cli(); }
|
||||
|
||||
static void hal_debug_set_mode(__xdata union hal_uart_config_t *cfg);
|
||||
#if (DEBUG_UART == USART0_P0) || (DEBUG_UART == USART0_P1)
|
||||
#define DEBUG_ISR(void) hal_uart_tx_interrupt(void) __interrupt UTX0_VECTOR
|
||||
#define HAL_DEBUG_ISR_FLAG_SET() (1)
|
||||
#define HAL_DEBUG_ISR_CLEAR_FLAG() { UTX0IF = 0; }
|
||||
#define HAL_DEBUG_ISR_DISABLE() { IEN2 &= ~(IEN2_UTX0IE); }
|
||||
#define HAL_DEBUG_TX_DATA(data) { U0DBUF = data; }
|
||||
#else
|
||||
#define DEBUG_ISR(void) hal_uart_tx_interrupt(void) __interrupt UTX1_VECTOR
|
||||
#define HAL_DEBUG_ISR_FLAG_SET() (1)
|
||||
#define HAL_DEBUG_ISR_CLEAR_FLAG() { UTX1IF = 0; }
|
||||
#define HAL_DEBUG_ISR_DISABLE() { IEN2 &= ~(IEN2_UTX1IE); }
|
||||
#define HAL_DEBUG_TX_DATA(data) { U1DBUF = data; }
|
||||
#endif // DEBUG_UART == ...
|
||||
|
||||
#endif // HAL_DEBUG_H_
|
||||
29
OpenSky/arch/cc251x/hal_defines.h
Normal file
29
OpenSky/arch/cc251x/hal_defines.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef __HAL_DEFINES_H__
|
||||
#define __HAL_DEFINES_H__
|
||||
|
||||
#define EXTERNAL_MEMORY __xdata
|
||||
#define EXTERNAL_DATA __data
|
||||
#define inline
|
||||
|
||||
#define sei() { IEN0 |= IEN0_EA; }
|
||||
#define cli() { IEN0 &= ~IEN0_EA; }
|
||||
|
||||
#ifndef NOP
|
||||
#define NOP() { __asm nop __endasm; }
|
||||
#endif
|
||||
#define NOP45() { NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
||||
|
||||
#define HI(a) (uint8_t) ((uint16_t)(a) >> 8 )
|
||||
#define LO(a) (uint8_t) (uint16_t)(a)
|
||||
#define SET_WORD(H, L, val) { (H) = HI(val); (L) = LO(val); }
|
||||
// necessary for timer registers. todo: check if necessary for others as well...
|
||||
#define SET_WORD_LO_FIRST(H, L, val) {(L) = LO(val); (H) = HI(val); }
|
||||
|
||||
#define UNUSED(x) (void)(x);
|
||||
|
||||
#define USART0_P0 0
|
||||
#define USART0_P1 1
|
||||
#define USART1_P0 2
|
||||
#define USART1_P1 3
|
||||
|
||||
#endif // __HAL_DEFINES_H__
|
||||
58
OpenSky/arch/cc251x/hal_delay.c
Normal file
58
OpenSky/arch/cc251x/hal_delay.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "hal_delay.h"
|
||||
|
||||
// busy wait delay loop. not 100% accurate
|
||||
void hal_delay_ms(uint16_t ms) {
|
||||
#define DELAY_MS_LOOP_A 86
|
||||
#define DELAY_MS_LOOP_B 30
|
||||
|
||||
while (ms--) {
|
||||
// this asm snippet gives us roughly 1ms delay:
|
||||
__asm
|
||||
mov r1, #DELAY_MS_LOOP_A
|
||||
00000$: // delay_ms_loop_outer
|
||||
dec r1
|
||||
mov a, r1
|
||||
jz 00002$
|
||||
mov r2, #DELAY_MS_LOOP_B
|
||||
00001$: // delay_ms_loop_inner
|
||||
dec r2
|
||||
mov a, r2
|
||||
jz 00000$
|
||||
sjmp 00001$
|
||||
00002$: // delay_ms_done
|
||||
__endasm;
|
||||
}
|
||||
}
|
||||
|
||||
// busy wait delay loop
|
||||
// this is more or less accurate
|
||||
void hal_delay_us(uint16_t us) {
|
||||
#define DELAY_US_LOOP 1
|
||||
|
||||
while (us--) {
|
||||
__asm
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
__endasm;
|
||||
}
|
||||
}
|
||||
28
OpenSky/arch/cc251x/hal_delay.h
Normal file
28
OpenSky/arch/cc251x/hal_delay.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_DELAY_H_
|
||||
#define HAL_DELAY_H_
|
||||
#include <stdint.h>
|
||||
|
||||
void hal_delay_ms(uint16_t ms);
|
||||
void hal_delay_us(uint16_t us);
|
||||
#define hal_delay_45nop(void) { uint8_t n=45; while (n--) { NOP(); } }
|
||||
|
||||
#endif // HAL_DELAY_H_
|
||||
26
OpenSky/arch/cc251x/hal_dma.c
Normal file
26
OpenSky/arch/cc251x/hal_dma.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "hal_dma.h"
|
||||
|
||||
// dma config
|
||||
// dma0 can be given independently but 1-4 has
|
||||
// to be given in one consequent array...
|
||||
__xdata HAL_DMA_DESC hal_dma_config[5];
|
||||
152
OpenSky/arch/cc251x/hal_dma.h
Normal file
152
OpenSky/arch/cc251x/hal_dma.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_DMA_H_
|
||||
#define HAL_DMA_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// HAL_DMA CONFIG
|
||||
// see https:// e2e.ti.com/support/wireless_connectivity/f/156/t/16922
|
||||
typedef struct {
|
||||
uint8_t SRCADDRH;
|
||||
uint8_t SRCADDRL;
|
||||
uint8_t DESTADDRH;
|
||||
uint8_t DESTADDRL;
|
||||
uint8_t LENH : 5;
|
||||
uint8_t VLEN : 3;
|
||||
uint8_t LENL : 8;
|
||||
uint8_t TRIG : 5;
|
||||
uint8_t TMODE : 2;
|
||||
uint8_t WORDSIZE : 1;
|
||||
uint8_t PRIORITY : 2;
|
||||
uint8_t M8 : 1;
|
||||
uint8_t IRQMASK : 1;
|
||||
uint8_t DESTINC : 2;
|
||||
uint8_t SRCINC : 2;
|
||||
} HAL_DMA_DESC;
|
||||
|
||||
extern __xdata HAL_DMA_DESC hal_dma_config[5];
|
||||
|
||||
// Use LEN for transfer count
|
||||
#define DMA_VLEN_USE_LEN 0x00
|
||||
// Transfer the number of bytes specified by the first byte +1
|
||||
#define DMA_VLEN_FIRST_BYTE_P_1 0x01
|
||||
// Transfer the number of bytes indicated by the first byte (itself included)
|
||||
#define DMA_VLEN_FIRST_BYTE 0x02
|
||||
// Transfer the number of bytes specified by the first byte +2
|
||||
#define DMA_VLEN_FIRST_BYTE_P_2 0x03
|
||||
// Transfer the number of bytes specified by the first byte +3
|
||||
#define DMA_VLEN_FIRST_BYTE_P_3 0x04
|
||||
// The maximum length is always decided by the first byte
|
||||
#define DMA_LEN_MAX 0xFF
|
||||
// Transfer a byte at a time
|
||||
#define DMA_WORDSIZE_BYTE 0x00
|
||||
// Transfer a 16-bit word at a time
|
||||
#define DMA_WORDSIZE_WORD 0x01
|
||||
// Transfer a single byte/word after each DMA trigger
|
||||
#define DMA_TMODE_SINGLE 0x00
|
||||
// Transfer block of data (length len) after each DMA trigger
|
||||
#define DMA_TMODE_BLOCK 0x01
|
||||
// Transfer single byte/word (after len transfers, rearm DMA)
|
||||
#define DMA_TMODE_SINGLE_REPEATED 0x02
|
||||
// Transfer block of data (after len transfers, rearm DMA)
|
||||
#define DMA_TMODE_BLOCK_REPEATED 0x03
|
||||
|
||||
#define DMA_TRIG_NONE 0 // No trigger, setting DMAREQ.DMAREQx bit starts transfer
|
||||
#define DMA_TRIG_PREV 1 // DMA channel is triggered by completion of previous channel
|
||||
#define DMA_TRIG_T1_CH0 2 // Timer 1, compare, channel 0
|
||||
#define DMA_TRIG_T1_CH1 3 // Timer 1, compare, channel 1
|
||||
#define DMA_TRIG_T1_CH2 4 // Timer 1, compare, channel 2
|
||||
#define DMA_TRIG_T2_COMP 5 // Timer 2, compare
|
||||
#define DMA_TRIG_T2_OVFL 6 // Timer 2, overflow
|
||||
#define DMA_TRIG_T3_CH0 7 // Timer 3, compare, channel 0
|
||||
#define DMA_TRIG_T3_CH1 8 // Timer 3, compare, channel 1
|
||||
#define DMA_TRIG_T4_CH0 9 // Timer 4, compare, channel 0
|
||||
#define DMA_TRIG_T4_CH1 10 // Timer 4, compare, channel 1
|
||||
#define DMA_TRIG_ST 11 // Sleep Timer compare
|
||||
#define DMA_TRIG_IOC_0 12 // Port 0 I/O pin input transition
|
||||
#define DMA_TRIG_IOC_1 13 // Port 1 I/O pin input transition
|
||||
#define DMA_TRIG_URX0 14 // USART0 RX complete
|
||||
#define DMA_TRIG_UTX0 15 // USART0 TX complete
|
||||
#define DMA_TRIG_URX1 16 // USART1 RX complete
|
||||
#define DMA_TRIG_UTX1 17 // USART1 TX complete
|
||||
#define DMA_TRIG_FLASH 18 // Flash data write complete
|
||||
#define DMA_TRIG_RADIO 19 // RF packet byte received/transmit
|
||||
#define DMA_TRIG_ADC_CHALL 20 // ADC end of a conversion in a sequence, sample ready
|
||||
#define DMA_TRIG_ADC_CH0 21 // ADC end of conversion channel 0 in sequence, sample ready
|
||||
#define DMA_TRIG_ADC_CH1 22 // ADC end of conversion channel 1 in sequence, sample ready
|
||||
#define DMA_TRIG_ADC_CH2 23 // ADC end of conversion channel 2 in sequence, sample ready
|
||||
#define DMA_TRIG_ADC_CH3 24 // ADC end of conversion channel 3 in sequence, sample ready
|
||||
#define DMA_TRIG_ADC_CH4 25 // ADC end of conversion channel 4 in sequence, sample ready
|
||||
#define DMA_TRIG_ADC_CH5 26 // ADC end of conversion channel 5 in sequence, sample ready
|
||||
#define DMA_TRIG_ADC_CH6 27 // ADC end of conversion channel 6 in sequence, sample ready
|
||||
#define DMA_TRIG_ADC_CH7 28 // ADC end of conversion channel 7 in sequence, sample ready
|
||||
#define DMA_TRIG_ENC_DW 29 // AES encryption processor requests download input data
|
||||
#define DMA_TRIG_ENC_UP 30 // AES encryption processor requests upload output data
|
||||
|
||||
// Increment source pointer by 0 bytes/words after each transfer
|
||||
#define DMA_SRCINC_0 0x00
|
||||
// Increment source pointer by 1 bytes/words after each transfer
|
||||
#define DMA_SRCINC_1 0x01
|
||||
// Increment source pointer by 2 bytes/words after each transfer
|
||||
#define DMA_SRCINC_2 0x02
|
||||
// Decrement source pointer by 1 bytes/words after each transfer
|
||||
#define DMA_SRCINC_M1 0x03
|
||||
|
||||
// Increment destination pointer by 0 bytes/words after each transfer
|
||||
#define DMA_DESTINC_0 0x00
|
||||
// Increment destination pointer by 1 bytes/words after each transfer
|
||||
#define DMA_DESTINC_1 0x01
|
||||
// Increment destination pointer by 2 bytes/words after each transfer
|
||||
#define DMA_DESTINC_2 0x02
|
||||
// Decrement destination pointer by 1 bytes/words after each transfer
|
||||
#define DMA_DESTINC_M1 0x03
|
||||
|
||||
// Disable interrupt generation
|
||||
#define DMA_IRQMASK_DISABLE 0x00
|
||||
// Enable interrupt generation upon DMA channel done
|
||||
#define DMA_IRQMASK_ENABLE 0x01
|
||||
|
||||
#define DMA_M8_USE_8_BITS 0x00 // Use all 8 bits for transfer count
|
||||
#define DMA_M8_USE_7_BITS 0x01 // Use 7 LSB for transfer count
|
||||
|
||||
// Low, CPU has priority
|
||||
#define DMA_PRI_LOW 0x00
|
||||
// Guaranteed, DMA at least every second try
|
||||
#define DMA_PRI_GUARANTEED 0x01
|
||||
// High, DMA has priority
|
||||
#define DMA_PRI_HIGH 0x02
|
||||
// Highest, DMA has priority. Reserved for DMA port access.
|
||||
#define DMA_PRI_ABSOLUTE 0x03
|
||||
|
||||
#define DMA_ARM_ABORT 0x80
|
||||
#define DMA_ARM_CH0 (1<<0)
|
||||
#define DMA_ARM_CH1 (1<<1)
|
||||
#define DMA_ARM_CH2 (1<<2)
|
||||
#define DMA_ARM_CH3 (1<<3)
|
||||
#define DMA_ARM_CH4 (1<<4)
|
||||
|
||||
#define DMAIRQ_DMAIF0 (1<<0)
|
||||
#define DMAIRQ_DMAIF1 (1<<1)
|
||||
#define DMAIRQ_DMAIF2 (1<<2)
|
||||
#define DMAIRQ_DMAIF3 (1<<3)
|
||||
#define DMAIRQ_DMAIF4 (1<<4)
|
||||
|
||||
#endif // HAL_DMA_H_
|
||||
56
OpenSky/arch/cc251x/hal_io.c
Normal file
56
OpenSky/arch/cc251x/hal_io.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "hal_io.h"
|
||||
#include "portmacros.h"
|
||||
#include "config.h"
|
||||
#include "hal_cc25xx.h"
|
||||
|
||||
void hal_io_init(void) {
|
||||
// set bind pin as input
|
||||
PORT2DIR(BIND_PORT) &= ~(1 << BIND_PIN);
|
||||
// set pullup/down
|
||||
PORT2INP(BIND_PORT) &= ~(1 << BIND_PIN);
|
||||
|
||||
#ifdef BIND2_PORT
|
||||
// this board allows two bind buttons, both will work
|
||||
// set bind2 pin as input
|
||||
PORT2DIR(BIND2_PORT) &= ~(1 << BIND2_PIN);
|
||||
// set pullup/down
|
||||
PORT2INP(BIND2_PORT) &= ~(1 << BIND2_PIN);
|
||||
#endif // BIND2_PORT
|
||||
}
|
||||
|
||||
uint8_t hal_io_bind_request(void) {
|
||||
// test bind button
|
||||
if (!(BIND_PORT & (1 << BIND_PIN))) {
|
||||
// LOW -> button pressed
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef BIND2_PORT
|
||||
if (!(BIND2_PORT & (1 << BIND2_PIN))) {
|
||||
// LOW -> button2 pressed
|
||||
return 1;
|
||||
}
|
||||
#endif // BIND2_PORT
|
||||
|
||||
// no button pressed...
|
||||
return 0;
|
||||
}
|
||||
29
OpenSky/arch/cc251x/hal_io.h
Normal file
29
OpenSky/arch/cc251x/hal_io.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_IO_H_
|
||||
#define HAL_IO_H_
|
||||
#include "portmacros.h"
|
||||
#include "config.h"
|
||||
#include <stdint.h>
|
||||
|
||||
void hal_io_init(void);
|
||||
uint8_t hal_io_bind_request(void);
|
||||
|
||||
#endif // HAL_IO_H_
|
||||
22
OpenSky/arch/cc251x/hal_led.c
Normal file
22
OpenSky/arch/cc251x/hal_led.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "hal_led.h"
|
||||
|
||||
// nothing to do
|
||||
44
OpenSky/arch/cc251x/hal_led.h
Normal file
44
OpenSky/arch/cc251x/hal_led.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_LED_H_
|
||||
#define HAL_LED_H_
|
||||
|
||||
#include "portmacros.h"
|
||||
#include "config.h"
|
||||
#include "hal_cc25xx.h"
|
||||
|
||||
// use helper macros to do expansion to *DIR etc
|
||||
// LEDS
|
||||
#define LED_GREEN_DIR PORT2DIR(LED_GREEN_PORT)
|
||||
#define LED_RED_DIR PORT2DIR(LED_RED_PORT)
|
||||
#define LED_RED_BIT PORT2BIT(LED_RED_PORT, LED_RED_PIN)
|
||||
#define LED_GREEN_BIT PORT2BIT(LED_GREEN_PORT, LED_GREEN_PIN)
|
||||
|
||||
#define hal_led_green_init() { LED_GREEN_DIR |= (1 << LED_GREEN_PIN); led_green_off(); }
|
||||
#define hal_led_green_on() { LED_GREEN_BIT = 1; }
|
||||
#define hal_led_green_off() { LED_GREEN_BIT = 0; }
|
||||
#define hal_led_green_toggle() { LED_GREEN_BIT = !LED_GREEN_BIT; }
|
||||
|
||||
#define hal_led_red_init() { LED_RED_DIR |= (1 << LED_RED_PIN); led_red_off(); }
|
||||
#define hal_led_red_on() { LED_RED_BIT = 1; }
|
||||
#define hal_led_red_off() { LED_RED_BIT = 0; }
|
||||
#define hal_led_red_toggle() { LED_RED_BIT = !LED_RED_BIT; }
|
||||
|
||||
#endif // HAL_LED_H_
|
||||
116
OpenSky/arch/cc251x/hal_ppm.c
Normal file
116
OpenSky/arch/cc251x/hal_ppm.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "hal_ppm.h"
|
||||
#include "ppm.h"
|
||||
|
||||
#ifndef SBUS_ENABLED
|
||||
|
||||
void hal_ppm_init(void) {
|
||||
// no int on overflow:
|
||||
OVFIM = 0;
|
||||
|
||||
// set channels to compare interupt:
|
||||
// CH0: off
|
||||
T1CCTL0 = 0;
|
||||
// CH1: off
|
||||
T1CCTL1 = 0;
|
||||
// CH2: toggle pin on cmp match, will generate sync pulses
|
||||
#if PPM_INVERTED
|
||||
// inverted, set on match, clear on zero
|
||||
T1CCTL2 = T1CCTLx_MODE_COMPARE | T1CCTLx_CMP_SETCLR0;
|
||||
#else
|
||||
// non-inverted, clear on match, set on zero
|
||||
T1CCTL2 = T1CCTLx_MODE_COMPARE | T1CCTLx_CMP_CLRSET0;
|
||||
#endif // PPM_INVERTED
|
||||
|
||||
// configure peripheral alternative1 for timer 1:
|
||||
// use alt config 1 -> clr flag -> P0_4 = output
|
||||
PERCFG &= ~(PERCFG_T1CFG);
|
||||
|
||||
// USART1 use ALT2 in order to free up P0_4 for peripheral func
|
||||
PERCFG |= PERCFG_U1CFG;
|
||||
|
||||
// select P0_4 for peripheral function
|
||||
// NOTE: make sure to set usart1 to alt2 config!
|
||||
P0SEL |= (1 << PPM_OUT_PIN);
|
||||
|
||||
// select P0_4 as output
|
||||
P0DIR |= (1 << PPM_OUT_PIN);
|
||||
|
||||
// prescaler = 128
|
||||
// tickspeed = 26MHz / 8 = 3,25MHz (TICKSPD is set in timeout.c!)
|
||||
// 1us = 3.25 ticks -> 2ms = 6500 ticks, 4ms = 13000
|
||||
T1CTL = T1CTL_MODE_MODULO | T1CTL_DIV_1;
|
||||
|
||||
|
||||
// ch2 cmp: sync pulse length
|
||||
SET_WORD_LO_FIRST(T1CC2H, T1CC2L, PPM_SYNC_PULS_LEN_TICKS);
|
||||
|
||||
// overflow:
|
||||
SET_WORD_LO_FIRST(T1CC0H, T1CC0L, HAL_PPM_US_TO_TICKCOUNT(1000));
|
||||
|
||||
ppm_output_index = 0;
|
||||
|
||||
// clear pending interrupt flags (IRCON is reset by hw)
|
||||
T1CTL &= ~(T1CTL_CH0_IF | T1CTL_CH1_IF | T1CTL_CH2_IF | T1CTL_OVFIF);
|
||||
|
||||
// overflow causes an int -> reload next channel data
|
||||
OVFIM = 1;
|
||||
|
||||
// enable T1 interrups
|
||||
T1IE = 1;
|
||||
}
|
||||
|
||||
|
||||
void hal_ppm_failsafe_exit() {
|
||||
// configure p0_4 as peripheral:
|
||||
P0SEL |= (1<<4);
|
||||
|
||||
// reset counter:
|
||||
SET_WORD_LO_FIRST(T1CNTH, T1CNTL, 0);
|
||||
|
||||
// re enable timer interrupts:
|
||||
OVFIM = 1;
|
||||
|
||||
// disable T1 interrups
|
||||
T1IE = 1;
|
||||
}
|
||||
|
||||
void hal_ppm_failsafe_enter(void) {
|
||||
// disable interrupts
|
||||
OVFIM = 0;
|
||||
|
||||
// disable T1 interrups
|
||||
T1IE = 0;
|
||||
|
||||
// configure p0_4 as normal i/o:
|
||||
P0SEL &= ~(1<<4);
|
||||
|
||||
// set pins to failsafe level:
|
||||
#if PPM_INVERTED
|
||||
// clear on zero -> default is high
|
||||
P0 |= (1<<4);
|
||||
#else
|
||||
// set on zero -> default is low
|
||||
P0 &= ~(1<<4);
|
||||
#endif // PPM_INVERTED
|
||||
}
|
||||
|
||||
#endif // SBUS_ENABLED
|
||||
68
OpenSky/arch/cc251x/hal_ppm.h
Normal file
68
OpenSky/arch/cc251x/hal_ppm.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_PPM_H_
|
||||
#define HAL_PPM_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "hal_cc25xx.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef SBUS_ENABLED
|
||||
#define hal_ppm_init() {}
|
||||
#else
|
||||
void hal_ppm_init(void);
|
||||
|
||||
void hal_ppm_failsafe_exit(void);
|
||||
void hal_ppm_failsafe_enter(void);
|
||||
|
||||
void hal_ppm_timer1_interrupt(void) __interrupt T1_VECTOR;
|
||||
|
||||
/*
|
||||
static void hal_ppm_init_rcc(void);
|
||||
static void hal_ppm_init_gpio(void);
|
||||
static void hal_ppm_init_timer(void);
|
||||
static void hal_ppm_init_nvic(void);
|
||||
static void hal_ppm_init_ocx(uint8_t ch, TIM_TypeDef *TIMx, TIM_OCInitTypeDef *tim_oc_init);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// from frsky to ticks coresponding to 1000...2000 us
|
||||
// frsky seems to send us*1.5 (~1480...3020) -> divide by 1.5 (=*2/3) to get us
|
||||
// us -> ticks = ((_us*13)/4) -> (((_frsky*2/3)*13)/4) = ((_frsky*13)/6)
|
||||
#define HAL_PPM_FRSKY_TO_TICKCOUNT(_frsky) (((_frsky << 3) + (_frsky << 2)+(_frsky))/6)
|
||||
|
||||
// from us to ticks:
|
||||
// ((_us*13)/4) = ((_us * (8+4+1))/4) = (((_us<<3)+(_us<<2)+(_us))>>2)
|
||||
#define HAL_PPM_US_TO_TICKCOUNT(_us) (((_us << 3) + (_us << 2)+(_us)) >> 2)
|
||||
|
||||
|
||||
#define PPM_TIMER_ISR(void) hal_ppm_timer1_interrupt(void) __interrupt T1_VECTOR
|
||||
|
||||
#define HAL_PPM_UPDATE_CCVALUE(val) SET_WORD_LO_FIRST(T1CC0H, T1CC0L, val)
|
||||
#define HAL_PPM_ISR_DISABLE() { cli(); }
|
||||
#define HAL_PPM_ISR_ENABLE() { sei(); }
|
||||
#define HAL_PPM_ISR_FLAG_SET() (1)
|
||||
#define HAL_PPM_ISR_CLEAR_FLAG() { \
|
||||
T1CTL &= ~(T1CTL_CH0_IF | T1CTL_CH1_IF | T1CTL_CH2_IF | T1CTL_OVFIF);}
|
||||
|
||||
#endif // SBUS_ENABLED
|
||||
|
||||
#endif // HAL_PPM_H_
|
||||
22
OpenSky/arch/cc251x/hal_sbus.c
Normal file
22
OpenSky/arch/cc251x/hal_sbus.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "sbus.h"
|
||||
|
||||
|
||||
36
OpenSky/arch/cc251x/hal_sbus.h
Normal file
36
OpenSky/arch/cc251x/hal_sbus.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_SBUS_H_
|
||||
#define HAL_SBUS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hal_defines.h"
|
||||
#include "hal_uart.h"
|
||||
|
||||
// this helper routine will invert the data
|
||||
// stored in buffer in case the sbus is set
|
||||
// to inverted
|
||||
#ifdef SBUS_INVERTED
|
||||
#define HAL_SBUS_PREPARE_DATA(a) (0xFF ^ (a))
|
||||
#else
|
||||
#define HAL_SBUS_PREPARE_DATA(a) (a)
|
||||
#endif // SBUS_INVERTED
|
||||
|
||||
#endif // HAL_SBUS_H_
|
||||
151
OpenSky/arch/cc251x/hal_soft_serial.c
Normal file
151
OpenSky/arch/cc251x/hal_soft_serial.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "hal_soft_serial.h"
|
||||
#include "soft_serial.h"
|
||||
#include "debug.h"
|
||||
#include "delay.h"
|
||||
#include "led.h"
|
||||
#include "wdt.h"
|
||||
#include "config.h"
|
||||
#include "portmacros.h"
|
||||
#include "hal_cc25xx.h"
|
||||
|
||||
#ifndef HUB_TELEMETRY_ON_SBUS_UART
|
||||
|
||||
void hal_soft_serial_init(void) {
|
||||
debug("hal_soft_serial: init\n"); debug_flush();
|
||||
hal_soft_serial_init_gpio();
|
||||
hal_soft_serial_init_interrupts();
|
||||
}
|
||||
|
||||
void hal_soft_serial_init_gpio(void) {
|
||||
// set gpio as input
|
||||
PORT2DIR(HUB_TELEMETRY_PORT) &= ~(1 << HUB_TELEMETRY_PIN);
|
||||
}
|
||||
|
||||
void hal_soft_serial_init_interrupts(void) {
|
||||
OVFIM = 0;
|
||||
|
||||
// disable compare modes
|
||||
T4CCTL0 = 0;
|
||||
T4CCTL1 = 0;
|
||||
|
||||
// tickspeed = 26MHz / 8 = 3,25MHz (TICKSPD is set in hal_timeout.c!)
|
||||
// 1us = 3.25 ticks -> DIV2 -> 1us = 1.625 ticks
|
||||
T4CTL = T4CTL_DIV_2 | // /2
|
||||
T4CTL_START | // start
|
||||
T4CTL_OVFIM | // OVInt enabled
|
||||
T4CTL_CLR | // clear
|
||||
T4CTL_MODE_MODULO; // 01 = count to CC and the overflow
|
||||
|
||||
// ch0 cmp: bit length
|
||||
T4CC0 = HAL_SOFTSERIAL_BIT_DURATION_TICKS;
|
||||
|
||||
// clear pending interrupt flags (IRCON is reset by hw)
|
||||
T4OVFIF = 0;
|
||||
|
||||
// overflow causes an int -> reload next channel data
|
||||
OVFIM = 1;
|
||||
|
||||
// enable T4 interrups
|
||||
IEN1 |= IEN1_T4IE;
|
||||
|
||||
// clear pending port ints
|
||||
P0IFG = 0;
|
||||
P0IF = 0;
|
||||
|
||||
// enable interrupts on P0 4...7
|
||||
PICTL |= PICTL_P0IENH;
|
||||
P0SEL &= ~(1<<6);
|
||||
|
||||
// set edge:
|
||||
#ifdef HUB_TELEMETRY_INVERTED
|
||||
// rising edge triggers isr
|
||||
PICTL &= ~PICTL_P0ICON;
|
||||
#else
|
||||
// falling edge triggers isr
|
||||
PICTL |= PICTL_P0ICON;
|
||||
#endif // HUB_TELEMETRY_INVERTED
|
||||
|
||||
// T4 highest int prio (group4)
|
||||
IP0 |= (1 << 4);
|
||||
IP1 |= (1 << 4);
|
||||
// P0 highest int prio (group5)
|
||||
IP0 |= (1 << 5);
|
||||
IP1 |= (1 << 5);
|
||||
|
||||
// enable interrupts from P0
|
||||
P0IF = 0;
|
||||
P0IFG = 0;
|
||||
IEN1 |= IEN1_P0IE;
|
||||
}
|
||||
|
||||
|
||||
void hal_soft_serial_update_interrupt(void) __interrupt T4_VECTOR {
|
||||
if (T4OVFIF) {
|
||||
// DEBUG_PIN_TOGGLE();
|
||||
|
||||
// re-arm for the next bit
|
||||
HAL_SOFT_SERIAL_UPDATE_TOP_VALUE(HAL_SOFTSERIAL_BIT_DURATION_TICKS-1);
|
||||
|
||||
if (soft_serial_process_databit()) {
|
||||
// finished transmission, disable UP and enable IC isr
|
||||
IEN1 |= IEN1_P0IE;
|
||||
IEN1 &= ~IEN1_T4IE;
|
||||
}
|
||||
|
||||
// clear pending interrupt flags (IRCON is reset by hw)
|
||||
T4OVFIF = 0;
|
||||
P0IFG = 0;
|
||||
P0IF = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void hal_soft_serial_startbit_interrupt(void) __interrupt P0INT_VECTOR {
|
||||
uint8_t isr_cause = P0IFG;
|
||||
|
||||
// clear int flags WARNING: order seems to be important! CLR first IFG then IF!
|
||||
P0IFG = 0;
|
||||
// clear P0 int flags (important: several P0 pins can cause the isr, clean all of them!)
|
||||
P0IF = 0;
|
||||
|
||||
if (isr_cause & (1 << HUB_TELEMETRY_PIN)) {
|
||||
// DEBUG_PIN_TOGGLE();
|
||||
// reset t3 counter:
|
||||
T4CTL |= T4CTL_CLR;
|
||||
// disable IC interrupt (only compare match interrupts will follow)
|
||||
IEN1 &= ~IEN1_P0IE;
|
||||
// enable overflow isr
|
||||
IEN1 |= IEN1_T4IE;
|
||||
|
||||
// this is the startbit -> re synchronize the timer to this
|
||||
// by setting the next cc interrupt to 1/2 bit length:
|
||||
HAL_SOFT_SERIAL_UPDATE_TOP_VALUE((HAL_SOFTSERIAL_BIT_DURATION_TICKS / 2)-1);
|
||||
|
||||
// clear pending int flags
|
||||
P0IF = 0;
|
||||
T4OVFIF = 0;
|
||||
|
||||
// process
|
||||
soft_serial_process_startbit();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HUB_TELEMETRY_ON_SBUS_UART
|
||||
49
OpenSky/arch/cc251x/hal_soft_serial.h
Normal file
49
OpenSky/arch/cc251x/hal_soft_serial.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_SOFT_SERIAL_H_
|
||||
#define HAL_SOFT_SERIAL_H_
|
||||
|
||||
#include "hal_cc25xx.h"
|
||||
#include "cc2510fx.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HUB_TELEMETRY_ON_SBUS_UART
|
||||
|
||||
void hal_soft_serial_init(void);
|
||||
void hal_soft_serial_init_gpio(void);
|
||||
void hal_soft_serial_init_interrupts(void);
|
||||
|
||||
// at 9600 baud a bit duration is 1/9600s = 104.166667us
|
||||
// the counter counts in 1/1.625th of us -> 104.1667us * 1.625
|
||||
// = 169,27... -> 169 -> 0.16% error (thats ok..)
|
||||
#define HAL_SOFTSERIAL_BIT_DURATION_TICKS (169)
|
||||
|
||||
#define HUB_TELEMETRY_PIN_HI() (HUB_TELEMETRY_PORT & (1 << HUB_TELEMETRY_PIN))
|
||||
#define HUB_TELEMETRY_PIN_LO() (!HUB_TELEMETRY_PIN_HI())
|
||||
|
||||
#define HAL_SOFT_SERIAL_UPDATE_TOP_VALUE(x) { T4CC0 = x; }
|
||||
|
||||
extern void hal_soft_serial_update_interrupt(void) __interrupt T4_VECTOR;
|
||||
extern void hal_soft_serial_startbit_interrupt(void) __interrupt P0INT_VECTOR;
|
||||
|
||||
#endif // HUB_TELEMETRY_ON_SBUS_UART
|
||||
|
||||
#endif // HAL_SOFT_SERIAL_H_
|
||||
|
||||
24
OpenSky/arch/cc251x/hal_spi.c
Normal file
24
OpenSky/arch/cc251x/hal_spi.c
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "hal_spi.h"
|
||||
|
||||
void hal_spi_init(void) {
|
||||
}
|
||||
|
||||
26
OpenSky/arch/cc251x/hal_spi.h
Normal file
26
OpenSky/arch/cc251x/hal_spi.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_SPI_H_
|
||||
#define HAL_SPI_H_
|
||||
|
||||
void hal_spi_init(void);
|
||||
|
||||
#endif // HAL_SPI_H_
|
||||
|
||||
205
OpenSky/arch/cc251x/hal_storage.c
Normal file
205
OpenSky/arch/cc251x/hal_storage.c
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "hal_storage.h"
|
||||
#include <cc2510fx.h>
|
||||
#include "debug.h"
|
||||
#include "main.h"
|
||||
#include "delay.h"
|
||||
#include "wdt.h"
|
||||
|
||||
|
||||
__xdata HAL_DMA_DESC flash_dma_config;
|
||||
// no ini value -> sdcc does not init this!
|
||||
__code __at(STORAGE_LOCATION) uint8_t storage_on_flash[STORAGE_PAGE_SIZE];
|
||||
|
||||
void hal_storage_init(void) {
|
||||
debug("hal_storage: init\n"); debug_flush();
|
||||
}
|
||||
|
||||
void hal_storage_write(uint8_t *buffer, uint16_t len) {
|
||||
hal_storage_flash_write((uint16_t)storage_on_flash, buffer, len);
|
||||
}
|
||||
|
||||
void hal_storage_read(uint8_t *storage_ptr, uint16_t len) {
|
||||
uint16_t i;
|
||||
|
||||
debug("hal_storage: loading from flash: "); debug_flush();
|
||||
|
||||
// copy from persistant flash to ram:
|
||||
for (i = 0; i < len; i++) {
|
||||
storage_ptr[i] = storage_on_flash[i];
|
||||
debug_put_hex8(storage_on_flash[i]); debug_putc(' '); debug_flush();
|
||||
wdt_reset();
|
||||
}
|
||||
}
|
||||
|
||||
static void hal_storage_flash_write(uint16_t address, uint8_t *data, uint16_t len) {
|
||||
uint16_t i = 0;
|
||||
uint8_t *flash_ptr = 0;
|
||||
|
||||
debug("hal_storage: will write page at 0x"); debug_flush();
|
||||
debug_put_hex8(address >> 8);
|
||||
debug_put_hex8(address & 0xff);
|
||||
debug_put_newline();
|
||||
|
||||
// this is VERY important:
|
||||
// make sure to write an even number of bytes!
|
||||
// simply write one extra byte
|
||||
if (len & 0x0001) {
|
||||
debug("flash: corrected len to even\n");
|
||||
len++;
|
||||
}
|
||||
|
||||
// disable interrupts
|
||||
cli();
|
||||
|
||||
// cancel _ALL_ ongoing DMA transfers:
|
||||
DMAARM = DMA_ARM_ABORT | 0x1F;
|
||||
|
||||
// high prio
|
||||
flash_dma_config.PRIORITY = DMA_PRI_HIGH;
|
||||
// irrelevant since we use LEN for transfer count
|
||||
flash_dma_config.M8 = DMA_M8_USE_8_BITS;
|
||||
// disable ints from this ch
|
||||
flash_dma_config.IRQMASK = DMA_IRQMASK_DISABLE;
|
||||
// use dma flash data write complete trigger
|
||||
flash_dma_config.TRIG = DMA_TRIG_FLASH;
|
||||
// single mode, see datasheet
|
||||
flash_dma_config.TMODE = DMA_TMODE_SINGLE;
|
||||
// one byte
|
||||
flash_dma_config.WORDSIZE = DMA_WORDSIZE_BYTE;
|
||||
|
||||
// set src: address of data to be written
|
||||
SET_WORD(flash_dma_config.SRCADDRH, flash_dma_config.SRCADDRL, data);
|
||||
// destination is flash controller data reg
|
||||
SET_WORD(flash_dma_config.DESTADDRH, flash_dma_config.DESTADDRL, &X_FWDATA);
|
||||
// use LEN
|
||||
flash_dma_config.VLEN = DMA_VLEN_USE_LEN;
|
||||
// set length
|
||||
SET_WORD(flash_dma_config.LENH, flash_dma_config.LENL, len);
|
||||
// set srcinc to 1 byte
|
||||
flash_dma_config.SRCINC = DMA_SRCINC_1;
|
||||
// fixed, always write to FWDATA
|
||||
flash_dma_config.DESTINC = DMA_DESTINC_0;
|
||||
|
||||
// Save pointer to the DMA configuration struct into DMA-channel 0
|
||||
// configuration registers
|
||||
SET_WORD(DMA0CFGH, DMA0CFGL, flash_dma_config);
|
||||
|
||||
// waiting for the flash controller to be ready
|
||||
while (FCTL & FCTL_BUSY) {}
|
||||
|
||||
// configure flash controller for 26mhz clock
|
||||
FWT = 0x2A; // (21 * 26) / (16);
|
||||
|
||||
// set up address:
|
||||
SET_WORD(FADDRH, FADDRL, ((uint16_t)address)>>1);
|
||||
|
||||
// re enable ints
|
||||
sei();
|
||||
|
||||
debug("hal_storage: erasing page\n"); debug_flush();
|
||||
|
||||
// disable interrupts
|
||||
cli();
|
||||
|
||||
// clear any pending flags
|
||||
DMAIRQ = 0;
|
||||
|
||||
// erase that page
|
||||
// has to be 2byte aligned. use a hack to place it at a given adress:
|
||||
hal_storage_flash_erase_page();
|
||||
|
||||
// Wait for the erase operation to complete
|
||||
while (FCTL & FCTL_BUSY) {}
|
||||
|
||||
// FCTL = 0;
|
||||
|
||||
// re enable ints
|
||||
sei();
|
||||
|
||||
debug("hal_storage: erase done\n"); debug_flush();
|
||||
|
||||
debug("hal_storage: will write ["); debug_flush();
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
debug_put_hex8(((uint8_t *)data)[i++]);
|
||||
debug_put_hex8(((uint8_t *)data)[i++]);
|
||||
debug_putc(' ');
|
||||
debug_flush();
|
||||
}
|
||||
debug("]\n");
|
||||
|
||||
debug("hal_storage: will write flash now\n"); debug_flush();
|
||||
|
||||
// disable interrupts
|
||||
cli();
|
||||
|
||||
// arm the DMA channel, so that a DMA trigger will initiate DMA writing
|
||||
DMAARM = DMA_ARM_CH0;
|
||||
NOP();
|
||||
|
||||
// enable flash write. this generates a DMA trigger.
|
||||
// must be aligned on a 2-byte boundary and is therefor implemented in assembly!
|
||||
hal_storage_flash_enable_write();
|
||||
|
||||
|
||||
// wait for dma finish
|
||||
while (!(DMAIRQ & DMAIRQ_DMAIF0)) {
|
||||
wdt_reset();
|
||||
}
|
||||
|
||||
// wait until flash controller not busy
|
||||
while (FCTL & (FCTL_BUSY | FCTL_SWBUSY)) {}
|
||||
|
||||
sei();
|
||||
|
||||
// by now, the transfer is completed, so the transfer count is reached.
|
||||
// the DMA channel 0 interrupt flag is then set, so we clear it here.
|
||||
DMAIRQ &= ~DMAIRQ_DMAIF0;
|
||||
|
||||
|
||||
debug("hal_storage: read back [");
|
||||
// copy from persistant flash to ram:
|
||||
flash_ptr = address;
|
||||
for (i = 0; i < len; i++) {
|
||||
debug_put_hex8(*flash_ptr++); debug_putc(' '); debug_flush();
|
||||
wdt_reset();
|
||||
}
|
||||
debug("]\n");
|
||||
|
||||
debug("hal_storage: write done");
|
||||
}
|
||||
|
||||
void hal_storage_flash_enable_write(void) {
|
||||
__asm
|
||||
.even // IMPORTANT: PLACE THIS ON A 2BYTE BOUNDARY!
|
||||
ORL _FCTL, #0x02; // FCTL |= FCTL_WRITE
|
||||
NOP;
|
||||
__endasm;
|
||||
}
|
||||
|
||||
void hal_storage_flash_erase_page(void) {
|
||||
__asm
|
||||
.even // IMPORTANT: PLACE THIS ON A 2BYTE BOUNDARY!
|
||||
ORL _FCTL, #0x01; // FCTL |= FCTL_ERASE
|
||||
NOP; // required sequence!
|
||||
__endasm;
|
||||
}
|
||||
45
OpenSky/arch/cc251x/hal_storage.h
Normal file
45
OpenSky/arch/cc251x/hal_storage.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_STORAGE_H_
|
||||
#define HAL_STORAGE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hal_cc25xx.h"
|
||||
#include "hal_dma.h"
|
||||
|
||||
// place data on end of flash
|
||||
// FIXME: this is for a cc2510f16 with flash size 0x4000, needs to be adjusted for bigger mcus
|
||||
#define STORAGE_PAGE_SIZE 1024
|
||||
#define STORAGE_LOCATION (0x4000-STORAGE_PAGE_SIZE)
|
||||
|
||||
// place persistant storage:
|
||||
extern __code __at(STORAGE_LOCATION) uint8_t storage_on_flash[STORAGE_PAGE_SIZE];
|
||||
extern __xdata HAL_DMA_DESC flash_dma_config;
|
||||
|
||||
|
||||
void hal_storage_init(void);
|
||||
void hal_storage_write(uint8_t *buffer, uint16_t len);
|
||||
void hal_storage_read(uint8_t *storage_ptr, uint16_t len);
|
||||
|
||||
static void hal_storage_flash_write(uint16_t address, uint8_t *data, uint16_t len);
|
||||
void hal_storage_flash_enable_write(void);
|
||||
void hal_storage_flash_erase_page(void);
|
||||
|
||||
#endif // HAL_STORAGE_H_
|
||||
135
OpenSky/arch/cc251x/hal_timeout.c
Normal file
135
OpenSky/arch/cc251x/hal_timeout.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "hal_timeout.h"
|
||||
#include "delay.h"
|
||||
#include "debug.h"
|
||||
#include "timeout.h"
|
||||
#include "hal_cc25xx.h"
|
||||
|
||||
// do not place this in xdata (faster this way)
|
||||
volatile uint16_t hal_timeout_countdown;
|
||||
volatile uint16_t hal_timeout2_countdown;
|
||||
|
||||
void hal_timeout_init(void) {
|
||||
debug("hal_timeout: init\n"); debug_flush();
|
||||
|
||||
// timer clock
|
||||
CLKCON = (CLKCON & ~CLKCON_TICKSPD_111) | CLKCON_TICKSPD_011;
|
||||
|
||||
// prepare timer3 for 1/25th ms steps:
|
||||
// TICKSPD 011 -> /8 = 3250 kHz timer clock input
|
||||
T3CTL = T3CTL_DIV_2 | // /2
|
||||
T3CTL_START | // start
|
||||
T3CTL_OVFIM | // OVInt enabled
|
||||
T3CTL_CLR | // clear
|
||||
T3CTL_MODE_MODULO; // 01 = count to CC and the overflow
|
||||
|
||||
// 3250/2/65 = 25khz
|
||||
T3CC0 = 65-1;
|
||||
|
||||
// enable int
|
||||
IEN1 |= (IEN1_T3IE);
|
||||
|
||||
timeout_set(0);
|
||||
|
||||
/*LED_RED_OFF();
|
||||
while (1) {
|
||||
timeout_set(990);
|
||||
LED_GREEN_OFF();
|
||||
while (!timeout_timed_out()) {}
|
||||
timeout_set(10);
|
||||
LED_GREEN_ON();
|
||||
while (!timeout_timed_out()) {}
|
||||
}*/
|
||||
|
||||
/* // TEST timings
|
||||
P0DIR |= (1<<7);
|
||||
while (1) {
|
||||
timeout_set(1);
|
||||
while (!timeout_timed_out()) {}
|
||||
P0 |= (1<<7);
|
||||
LED_RED_ON();
|
||||
delay_ms(100);
|
||||
P0 &= ~(1<<7);
|
||||
LED_RED_OFF();
|
||||
}*/
|
||||
}
|
||||
|
||||
// prepare a new timeout
|
||||
void hal_timeout_set(uint16_t timeout_ms) {
|
||||
// disable T3ints:
|
||||
IEN1 &= ~(IEN1_T3IE);
|
||||
|
||||
// clear counter
|
||||
// T3CTL |= (1<<2);
|
||||
|
||||
// clear pending ints
|
||||
// T3IF = 0;
|
||||
|
||||
// prepare timeout val:
|
||||
hal_timeout_countdown = (timeout_ms * 25);
|
||||
|
||||
// clear pending ints
|
||||
// T3IF = 0;
|
||||
|
||||
// re enable interrupts
|
||||
IEN1 |= IEN1_T3IE;
|
||||
}
|
||||
|
||||
uint8_t hal_timeout_timed_out(void) {
|
||||
if (hal_timeout_countdown == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// prepare a new timeout
|
||||
void hal_timeout2_set_100us(uint16_t timeout_100us) {
|
||||
hal_timeout2_countdown = (timeout_100us * 25) / 10;
|
||||
}
|
||||
|
||||
// prepare a new timeout
|
||||
void hal_timeout2_set(uint16_t timeout_ms) {
|
||||
hal_timeout2_countdown = (timeout_ms * 25);
|
||||
}
|
||||
|
||||
|
||||
uint8_t hal_timeout2_timed_out(void) {
|
||||
if (hal_timeout2_countdown == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void hal_timeout_interrupt(void) __interrupt T3_VECTOR {
|
||||
// clear flag
|
||||
T3IF = 0;
|
||||
|
||||
if (hal_timeout_countdown != 0) {
|
||||
hal_timeout_countdown--;
|
||||
}
|
||||
|
||||
if (hal_timeout2_countdown != 0) {
|
||||
hal_timeout2_countdown--;
|
||||
}
|
||||
}
|
||||
38
OpenSky/arch/cc251x/hal_timeout.h
Normal file
38
OpenSky/arch/cc251x/hal_timeout.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_TIMEOUT_H_
|
||||
#define HAL_TIMEOUT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cc2510fx.h"
|
||||
|
||||
extern volatile uint16_t hal_timeout_countdown;
|
||||
|
||||
void hal_timeout_init(void);
|
||||
void hal_timeout_set(uint16_t timeout_ms);
|
||||
uint8_t hal_timeout_timed_out(void);
|
||||
|
||||
void hal_timeout2_set(uint16_t ms);
|
||||
void hal_timeout2_set_100us(uint16_t hus);
|
||||
uint8_t hal_timeout2_timed_out(void);
|
||||
|
||||
void hal_timeout_interrupt(void) __interrupt T3_VECTOR;
|
||||
|
||||
#endif // HAL_TIMEOUT_H_
|
||||
258
OpenSky/arch/cc251x/hal_uart.c
Normal file
258
OpenSky/arch/cc251x/hal_uart.c
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "cc2510fx.h"
|
||||
#include "hal_cc25xx.h"
|
||||
#include "hal_uart.h"
|
||||
#include "hal_defines.h"
|
||||
#include "hal_delay.h"
|
||||
#include "config.h"
|
||||
#include "hal_dma.h"
|
||||
#include "uart.h"
|
||||
#include "debug.h"
|
||||
#include "wdt.h"
|
||||
#include "delay.h"
|
||||
#include "led.h"
|
||||
|
||||
void hal_uart_init(void) {
|
||||
EXTERNAL_MEMORY union hal_uart_config_t sbus_uart_config;
|
||||
|
||||
#if SBUS_UART == USART0_P1
|
||||
// -> USART0_P1
|
||||
// use ALT2 -> Set flag -> P1_5 = TX / P1_4 = RX
|
||||
PERCFG |= (PERCFG_U0CFG);
|
||||
|
||||
// configure pins as peripheral:
|
||||
P1SEL |= (1<<5) | (1<<4);
|
||||
|
||||
// make sure all P0 pins switch to normal GPIO
|
||||
P0SEL &= ~(0x3C);
|
||||
|
||||
// make tx pin output:
|
||||
P1DIR |= (1<<5);
|
||||
#elif SBUS_UART == USART1_P0
|
||||
// USART1 use ALT1 -> Clear flag -> Port P0_4 = TX
|
||||
PERCFG &= ~(PERCFG_U1CFG);
|
||||
|
||||
// USART1 has priority when USART0 is also enabled
|
||||
P2DIR = (P2DIR & 0x3F) | 0b01000000;
|
||||
|
||||
// configure pin P0_4 (TX) and P0_5 (RX) as special function:
|
||||
P0SEL |= (1<<4) | (1<<5);
|
||||
|
||||
// make sure all P1 pins switch to normal GPIO
|
||||
// P1SEL &= ~(0xF0);
|
||||
|
||||
// make tx pin output:
|
||||
P0DIR |= (1<<4);
|
||||
#elif SBUS_UART == USART1_P1
|
||||
// USART1 use ALT2 -> SET flag -> Port P1_6 = TX
|
||||
PERCFG |= (PERCFG_U1CFG);
|
||||
|
||||
// USART1 has priority when USART0 is also enabled
|
||||
P2DIR = (P2DIR & 0x3F) | 0b01000000;
|
||||
|
||||
// configure pin P1_6 (TX) and P1_7(RX) as special function:
|
||||
P1SEL |= (1<<6) | (1<<7);
|
||||
|
||||
// make tx pin output:
|
||||
P1DIR |= (1<<6);
|
||||
#else
|
||||
#error "UNSUPPORTED UART"
|
||||
#endif // SBUS_UART == ...
|
||||
|
||||
// set baudrate
|
||||
#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
|
||||
U0BAUD = CC2510_BAUD_M_100000;
|
||||
U0GCR = (U0GCR & ~0x1F) | (CC2510_BAUD_E_100000);
|
||||
#else
|
||||
U1BAUD = CC2510_BAUD_M_100000;
|
||||
U1GCR = (U1GCR & ~0x1F) | (CC2510_BAUD_E_100000);
|
||||
#endif // SBUS_UART == ...
|
||||
|
||||
// set up config for USART -> 8E2
|
||||
#ifdef SBUS_INVERTED
|
||||
// this is a really nice feature of the cc2510:
|
||||
// we can invert the idle level of the usart
|
||||
// by setting STOP to zero. by inverting
|
||||
// the parity, the startbit, and the data
|
||||
// by using the SBUS_PREPARE_DATA() macro
|
||||
// we can effectively invert the usart in software :)
|
||||
sbus_uart_config.bit.START = 1; // startbit level = low
|
||||
sbus_uart_config.bit.STOP = 0; // stopbit level = high
|
||||
sbus_uart_config.bit.D9 = 1; // UNEven parity
|
||||
#else
|
||||
// standard usart, non-inverted mode
|
||||
// NOTE: most sbus implementations use inverted mode
|
||||
sbus_uart_config.bit.START = 0; // startbit level = low
|
||||
sbus_uart_config.bit.STOP = 1; // stopbit level = high
|
||||
sbus_uart_config.bit.D9 = 0; // Even parity
|
||||
#endif // SBUS_INVERTED
|
||||
|
||||
sbus_uart_config.bit.SPB = 1; // 1 = 2 stopbits
|
||||
sbus_uart_config.bit.PARITY = 1; // 1 = parity enabled, D9=0 -> even parity
|
||||
sbus_uart_config.bit.BIT9 = 1; // 8bit
|
||||
sbus_uart_config.bit.FLOW = 0; // no hw flow control
|
||||
sbus_uart_config.bit.ORDER = 0; // lsb first
|
||||
|
||||
// activate uart config
|
||||
hal_uart_set_mode(&sbus_uart_config);
|
||||
|
||||
// use dma channel 3 for transmission:
|
||||
hal_dma_config[3].PRIORITY = DMA_PRI_LOW;
|
||||
hal_dma_config[3].M8 = DMA_M8_USE_7_BITS;
|
||||
hal_dma_config[3].IRQMASK = DMA_IRQMASK_DISABLE;
|
||||
#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
|
||||
hal_dma_config[3].TRIG = DMA_TRIG_UTX0;
|
||||
#else
|
||||
hal_dma_config[3].TRIG = DMA_TRIG_UTX1;
|
||||
#endif // SBUS_UART == ...
|
||||
hal_dma_config[3].TMODE = DMA_TMODE_SINGLE;
|
||||
hal_dma_config[3].WORDSIZE = DMA_WORDSIZE_BYTE;
|
||||
|
||||
// source address will be set during tx start
|
||||
SET_WORD(hal_dma_config[3].SRCADDRH, hal_dma_config[3].SRCADDRL, 0);
|
||||
#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
|
||||
SET_WORD(hal_dma_config[3].DESTADDRH, hal_dma_config[3].DESTADDRL, &X_U0DBUF);
|
||||
#else
|
||||
SET_WORD(hal_dma_config[3].DESTADDRH, hal_dma_config[3].DESTADDRL, &X_U1DBUF);
|
||||
#endif // SBUS_UART == ...
|
||||
|
||||
hal_dma_config[3].VLEN = DMA_VLEN_USE_LEN;
|
||||
|
||||
// len will be set during tx start
|
||||
SET_WORD(hal_dma_config[3].LENH, hal_dma_config[3].LENL, 0);
|
||||
|
||||
// configure src and dest increments
|
||||
hal_dma_config[3].SRCINC = DMA_SRCINC_1;
|
||||
hal_dma_config[3].DESTINC = DMA_DESTINC_0;
|
||||
|
||||
// set pointer to the DMA configuration struct into DMA-channel 1-4
|
||||
// configuration, should have happened in adc.c already...
|
||||
SET_WORD(DMA1CFGH, DMA1CFGL, &hal_dma_config[1]);
|
||||
|
||||
// arm the relevant DMA channel for UART TX, and apply 45 NOP's
|
||||
// to allow the DMA configuration to load
|
||||
// -> do a sleep instead of those nops...
|
||||
DMAARM |= DMA_ARM_CH3;
|
||||
hal_delay_45nop();
|
||||
|
||||
#ifdef HUB_TELEMETRY_ON_SBUS_UART
|
||||
// activate serial rx interrupt
|
||||
#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
|
||||
URX0IF = 0;
|
||||
|
||||
// enable receiption
|
||||
U0CSR |= UxCSR_RX_ENABLE;
|
||||
|
||||
// enable RX interrupt
|
||||
URX0IE = 1;
|
||||
#else
|
||||
URX1IF = 0;
|
||||
|
||||
// enable receiption
|
||||
U1CSR |= UxCSR_RX_ENABLE;
|
||||
|
||||
// enable RX interrupt
|
||||
URX1IE = 1;
|
||||
#endif // HUB_TELEMETRY_ON_SBUS_UART
|
||||
|
||||
// enable global ints
|
||||
EA = 1;
|
||||
#endif // SBUS_UART == ...
|
||||
}
|
||||
|
||||
static void hal_uart_set_mode(EXTERNAL_MEMORY union hal_uart_config_t *cfg) {
|
||||
#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
|
||||
// enable uart mode
|
||||
U0CSR |= 0x80;
|
||||
|
||||
// store config to U1UCR register
|
||||
U0UCR = cfg->byte & (0x7F);
|
||||
|
||||
// store config to U1GCR: (msb/lsb)
|
||||
if (cfg->bit.ORDER) {
|
||||
U0GCR |= U0GCR_ORDER;
|
||||
} else {
|
||||
U0GCR &= ~U0GCR_ORDER;
|
||||
}
|
||||
|
||||
// interrupt prio to 1 (0..3=highest)
|
||||
IP0 |= (1<<2);
|
||||
IP1 &= ~(1<<2);
|
||||
#else
|
||||
// enable uart mode
|
||||
U1CSR |= 0x80;
|
||||
|
||||
// store config to U1UCR register
|
||||
U1UCR = cfg->byte & (0x7F);
|
||||
|
||||
// store config to U1GCR: (msb/lsb)
|
||||
if (cfg->bit.ORDER) {
|
||||
U1GCR |= U1GCR_ORDER;
|
||||
} else {
|
||||
U1GCR &= ~U1GCR_ORDER;
|
||||
}
|
||||
|
||||
// interrupt prio to 1 (0..3=highest)
|
||||
IP0 |= (1<<3);
|
||||
IP1 &= ~(1<<3);
|
||||
#endif // SBUS_UART
|
||||
}
|
||||
|
||||
void hal_uart_start_transmission(uint8_t *data, uint8_t len) {
|
||||
// important: src addr start is data[1]
|
||||
SET_WORD(hal_dma_config[3].SRCADDRH, hal_dma_config[3].SRCADDRL, &data[1]);
|
||||
|
||||
// configure length of transfer
|
||||
SET_WORD(hal_dma_config[3].LENH, hal_dma_config[3].LENL, len);
|
||||
|
||||
// time to send this frame!
|
||||
// re-arm dma:
|
||||
DMAARM |= DMA_ARM_CH3;
|
||||
|
||||
// 45 nops to make sure the dma config is loaded
|
||||
hal_delay_45nop();
|
||||
|
||||
// send the very first UART byte to trigger a UART TX session:
|
||||
#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
|
||||
U0DBUF = data[0];
|
||||
#else
|
||||
U1DBUF = data[0];
|
||||
#endif // SBUS_UART
|
||||
}
|
||||
|
||||
#ifdef HUB_TELEMETRY_ON_SBUS_UART
|
||||
void HAL_UART_RX_ISR(void) {
|
||||
uint8_t rx;
|
||||
|
||||
HAL_UART_RX_ISR_CLEAR_FLAG(); // THIS SHOULD NEVER BE THE LAST LINE IN AN ISR!
|
||||
|
||||
#ifdef SBUS_INVERTED
|
||||
rx = 0xFF ^ HAL_UART_RX_GETCH(); // remove data inversion
|
||||
#else
|
||||
rx = HAL_UART_RX_GETCH();
|
||||
#endif // SBUS_INVERTED
|
||||
|
||||
if (uart_rx_callback != 0) {
|
||||
// execute callback
|
||||
uart_rx_callback(rx);
|
||||
}
|
||||
}
|
||||
#endif // HUB_TELEMETRY_ON_SBUS_UART
|
||||
68
OpenSky/arch/cc251x/hal_uart.h
Normal file
68
OpenSky/arch/cc251x/hal_uart.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_UART_H_
|
||||
#define HAL_UART_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hal_defines.h"
|
||||
|
||||
// for a 26MHz Crystal:
|
||||
#define CC2510_BAUD_E_115200 12
|
||||
#define CC2510_BAUD_M_115200 34
|
||||
// best match for 100kbit/s = 99975.5859375 bit/s
|
||||
// baudrate = (((256.0 + baud_m)*2.0**baud_e) / (2**28)) * 26000000.0
|
||||
#define CC2510_BAUD_E_100000 11
|
||||
#define CC2510_BAUD_M_100000 248
|
||||
#define CC2510_BAUD_E_57600 11
|
||||
#define CC2510_BAUD_M_57600 34
|
||||
|
||||
union hal_uart_config_t{
|
||||
uint8_t byte;
|
||||
struct {
|
||||
uint8_t START : 1; // start bit level
|
||||
uint8_t STOP : 1; // stop bit level
|
||||
uint8_t SPB : 1; // stop bits (0=1, 1=2)
|
||||
uint8_t PARITY: 1; // parity (on/off)
|
||||
uint8_t BIT9 : 1; // 9 bit mode
|
||||
uint8_t D9 : 1; // 9th bit level or parity type
|
||||
uint8_t FLOW : 1; // flow control
|
||||
uint8_t ORDER : 1; // data bit order (LSB or MSB first)
|
||||
} bit;
|
||||
};
|
||||
|
||||
void hal_uart_init(void);
|
||||
static void hal_uart_set_mode(EXTERNAL_MEMORY union hal_uart_config_t *cfg);
|
||||
void hal_uart_start_transmission(uint8_t *data, uint8_t len);
|
||||
|
||||
#ifdef HUB_TELEMETRY_ON_SBUS_UART
|
||||
#if (SBUS_UART == USART0_P1) || (SBUS_UART == USART0_P0)
|
||||
#define HAL_UART_RX_ISR(void) hal_uart_rx_interrupt(void) __interrupt URX0_VECTOR
|
||||
#define HAL_UART_RX_ISR_CLEAR_FLAG() { URX0IF = 0; }
|
||||
#define HAL_UART_RX_GETCH() (U0DBUF)
|
||||
#else
|
||||
#define HAL_UART_RX_ISR(void) hal_uart_rx_interrupt(void) __interrupt URX1_VECTOR
|
||||
#define HAL_UART_RX_ISR_CLEAR_FLAG() { URX1IF = 0; }
|
||||
#define HAL_UART_RX_GETCH() (U1DBUF)
|
||||
#endif // SBUS_UART == ...
|
||||
|
||||
void HAL_UART_RX_ISR(void);
|
||||
#endif // HUB_TELEMETRY_ON_SBUS_UART
|
||||
|
||||
#endif // HAL_UART_H_
|
||||
50
OpenSky/arch/cc251x/hal_wdt.c
Normal file
50
OpenSky/arch/cc251x/hal_wdt.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#include "hal_wdt.h"
|
||||
#include "debug.h"
|
||||
#include "led.h"
|
||||
#include "delay.h"
|
||||
#include "hal_cc25xx.h"
|
||||
|
||||
void hal_wdt_init(void) {
|
||||
// check if 32khz clock source is rcosc:
|
||||
if (!(CLKCON & CLKCON_OSC32K)) {
|
||||
debug("wdt: error! low speed clock not based on int rc");
|
||||
led_green_on();
|
||||
while (1) {
|
||||
led_red_on();
|
||||
delay_ms(200);
|
||||
led_red_off();
|
||||
delay_ms(200);
|
||||
}
|
||||
}
|
||||
|
||||
// set wdt interval to approx 1 second
|
||||
WDCTL = (WDCTL & ~WDCTL_INT) | WDCTL_INT_1S;
|
||||
|
||||
// enable wdt. NOTE: this can not be disabled in software!
|
||||
WDCTL = (WDCTL & ~WDCTL_MODE) | WDCTL_EN;
|
||||
}
|
||||
|
||||
void hal_wdt_reset(void) {
|
||||
// reset wdt (special sequence)
|
||||
WDCTL = (WDCTL & 0x0F) | 0b10100000;
|
||||
WDCTL = (WDCTL & 0x0F) | 0b01010000;
|
||||
}
|
||||
26
OpenSky/arch/cc251x/hal_wdt.h
Normal file
26
OpenSky/arch/cc251x/hal_wdt.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright 2017 fishpepper <AT> gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http:// www.gnu.org/licenses/>.
|
||||
|
||||
author: fishpepper <AT> gmail.com
|
||||
*/
|
||||
|
||||
#ifndef HAL_WDT_H_
|
||||
#define HAL_WDT_H_
|
||||
|
||||
void hal_wdt_init(void);
|
||||
void hal_wdt_reset(void);
|
||||
|
||||
#endif // HAL_WDT_H_
|
||||
13
OpenSky/arch/cc251x/portmacros.h
Normal file
13
OpenSky/arch/cc251x/portmacros.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef __PORTMACROS_H__
|
||||
#define __PORTMACROS_H__
|
||||
|
||||
|
||||
#define PORT2DIR_(X) X ## DIR
|
||||
#define PORT2DIR(PORTNAME) PORT2DIR_(PORTNAME)
|
||||
#define PORT2BIT_(X,N) X ## _ ## N
|
||||
#define PORT2BIT(PORTNAME, PIN) PORT2BIT_(PORTNAME,PIN)
|
||||
#define PORT2INP_(X) X ## INP
|
||||
#define PORT2INP(PORTNAME) PORT2INP_(PORTNAME)
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user