Files
Maison/OpenSky/arch/cc251x/hal_soft_serial.c
2026-04-21 12:19:15 +02:00

152 lines
4.1 KiB
C

/*
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