mirror of
https://github.com/infiniteCable2/panda.git
synced 2026-02-18 09:13:52 +08:00
Merge branch 'upstream/master' into sync-20241122
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
unsigned char reserved : 1;
|
||||
unsigned char fd : 1;
|
||||
unsigned char bus : 3;
|
||||
unsigned char data_len_code : 4; // lookup length with dlc_to_len
|
||||
unsigned char rejected : 1;
|
||||
|
||||
@@ -89,6 +89,7 @@ void process_can(uint8_t can_number) {
|
||||
if ((CANx->TSR & CAN_TSR_RQCP0) == CAN_TSR_RQCP0) {
|
||||
if ((CANx->TSR & CAN_TSR_TXOK0) == CAN_TSR_TXOK0) {
|
||||
CANPacket_t to_push;
|
||||
to_push.fd = 0U;
|
||||
to_push.returned = 1U;
|
||||
to_push.rejected = 0U;
|
||||
to_push.extended = (CANx->sTxMailBox[0].TIR >> 2) & 0x1U;
|
||||
@@ -144,6 +145,7 @@ void can_rx(uint8_t can_number) {
|
||||
// add to my fifo
|
||||
CANPacket_t to_push;
|
||||
|
||||
to_push.fd = 0U;
|
||||
to_push.returned = 0U;
|
||||
to_push.rejected = 0U;
|
||||
to_push.extended = (CANx->sFIFOMailBox[0].RIR >> 2) & 0x1U;
|
||||
@@ -159,6 +161,7 @@ void can_rx(uint8_t can_number) {
|
||||
if (bus_fwd_num != -1) {
|
||||
CANPacket_t to_send;
|
||||
|
||||
to_send.fd = 0U;
|
||||
to_send.returned = 0U;
|
||||
to_send.rejected = 0U;
|
||||
to_send.extended = to_push.extended; // TXRQ
|
||||
|
||||
@@ -131,10 +131,10 @@ void can_clear(can_ring *q) {
|
||||
// Helpers
|
||||
// Panda: Bus 0=CAN1 Bus 1=CAN2 Bus 2=CAN3
|
||||
bus_config_t bus_config[BUS_CONFIG_ARRAY_SIZE] = {
|
||||
{ .bus_lookup = 0U, .can_num_lookup = 0U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 1U, .can_num_lookup = 1U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 2U, .can_num_lookup = 2U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 0xFFU, .can_num_lookup = 0xFFU, .forwarding_bus = -1, .can_speed = 333U, .can_data_speed = 333U, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 0U, .can_num_lookup = 0U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 1U, .can_num_lookup = 1U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 2U, .can_num_lookup = 2U, .forwarding_bus = -1, .can_speed = 5000U, .can_data_speed = 20000U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
{ .bus_lookup = 0xFFU, .can_num_lookup = 0xFFU, .forwarding_bus = -1, .can_speed = 333U, .can_data_speed = 333U, .canfd_auto = false, .canfd_enabled = false, .brs_enabled = false, .canfd_non_iso = false },
|
||||
};
|
||||
|
||||
void can_init_all(void) {
|
||||
@@ -165,7 +165,7 @@ void ignition_can_hook(CANPacket_t *to_push) {
|
||||
if (bus == 0) {
|
||||
int addr = GET_ADDR(to_push);
|
||||
int len = GET_LEN(to_push);
|
||||
|
||||
|
||||
// GM exception
|
||||
if ((addr == 0x1F1) && (len == 8)) {
|
||||
// SystemPowerMode (2=Run, 3=Crank Request)
|
||||
|
||||
@@ -13,6 +13,7 @@ typedef struct {
|
||||
int8_t forwarding_bus;
|
||||
uint32_t can_speed;
|
||||
uint32_t can_data_speed;
|
||||
bool canfd_auto;
|
||||
bool canfd_enabled;
|
||||
bool brs_enabled;
|
||||
bool canfd_non_iso;
|
||||
|
||||
@@ -100,7 +100,11 @@ void process_can(uint8_t can_number) {
|
||||
fifo = (canfd_fifo *)(TxFIFOSA + (tx_index * FDCAN_TX_FIFO_EL_SIZE));
|
||||
|
||||
fifo->header[0] = (to_send.extended << 30) | ((to_send.extended != 0U) ? (to_send.addr) : (to_send.addr << 18));
|
||||
uint32_t canfd_enabled_header = bus_config[can_number].canfd_enabled ? (1UL << 21) : 0UL;
|
||||
|
||||
// If canfd_auto is set, outgoing packets will be automatically sent as CAN-FD if an incoming CAN-FD packet was seen
|
||||
bool fd = bus_config[can_number].canfd_auto ? bus_config[can_number].canfd_enabled : (bool)(to_send.fd > 0U);
|
||||
uint32_t canfd_enabled_header = fd ? (1UL << 21) : 0UL;
|
||||
|
||||
uint32_t brs_enabled_header = bus_config[can_number].brs_enabled ? (1UL << 20) : 0UL;
|
||||
fifo->header[1] = (to_send.data_len_code << 16) | canfd_enabled_header | brs_enabled_header;
|
||||
|
||||
@@ -115,6 +119,7 @@ void process_can(uint8_t can_number) {
|
||||
// Send back to USB
|
||||
CANPacket_t to_push;
|
||||
|
||||
to_push.fd = fd;
|
||||
to_push.returned = 1U;
|
||||
to_push.rejected = 0U;
|
||||
to_push.extended = to_send.extended;
|
||||
@@ -168,6 +173,10 @@ void can_rx(uint8_t can_number) {
|
||||
// getting address
|
||||
fifo = (canfd_fifo *)(RxFIFO0SA + (rx_fifo_idx * FDCAN_RX_FIFO_0_EL_SIZE));
|
||||
|
||||
bool canfd_frame = ((fifo->header[1] >> 21) & 0x1U);
|
||||
bool brs_frame = ((fifo->header[1] >> 20) & 0x1U);
|
||||
|
||||
to_push.fd = canfd_frame;
|
||||
to_push.returned = 0U;
|
||||
to_push.rejected = 0U;
|
||||
to_push.extended = (fifo->header[0] >> 30) & 0x1U;
|
||||
@@ -175,9 +184,6 @@ void can_rx(uint8_t can_number) {
|
||||
to_push.bus = bus_number;
|
||||
to_push.data_len_code = ((fifo->header[1] >> 16) & 0xFU);
|
||||
|
||||
bool canfd_frame = ((fifo->header[1] >> 21) & 0x1U);
|
||||
bool brs_frame = ((fifo->header[1] >> 20) & 0x1U);
|
||||
|
||||
uint8_t data_len_w = (dlc_to_len[to_push.data_len_code] / 4U);
|
||||
data_len_w += ((dlc_to_len[to_push.data_len_code] % 4U) > 0U) ? 1U : 0U;
|
||||
for (unsigned int i = 0; i < data_len_w; i++) {
|
||||
@@ -193,6 +199,7 @@ void can_rx(uint8_t can_number) {
|
||||
if (bus_fwd_num != -1) {
|
||||
CANPacket_t to_send;
|
||||
|
||||
to_send.fd = to_push.fd;
|
||||
to_send.returned = 0U;
|
||||
to_send.rejected = 0U;
|
||||
to_send.extended = to_push.extended;
|
||||
|
||||
@@ -317,6 +317,10 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
|
||||
case 0xe7:
|
||||
set_power_save_state(req->param1);
|
||||
break;
|
||||
// **** 0xe8: set can-fd auto swithing mode
|
||||
case 0xe8:
|
||||
bus_config[req->param1].canfd_auto = req->param2 > 0U;
|
||||
break;
|
||||
// **** 0xf1: Clear CAN ring buffer.
|
||||
case 0xf1:
|
||||
if (req->param1 == 0xFFFFU) {
|
||||
|
||||
@@ -135,6 +135,7 @@ void peripherals_init(void) {
|
||||
RCC->APB1LENR |= RCC_APB1LENR_TIM7EN; // DMA trigger timer
|
||||
RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; // tick timer
|
||||
RCC->APB1LENR |= RCC_APB1LENR_TIM12EN; // slow loop
|
||||
RCC->APB1LENR |= RCC_APB1LENR_TIM5EN; // sound trigger timer
|
||||
|
||||
#ifdef PANDA_JUNGLE
|
||||
RCC->AHB3ENR |= RCC_AHB3ENR_SDMMC1EN; // SDMMC
|
||||
|
||||
@@ -5,31 +5,6 @@ __attribute__((section(".sram4"))) static uint16_t sound_rx_buf[2][SOUND_RX_BUF_
|
||||
|
||||
static uint8_t sound_idle_count;
|
||||
|
||||
// Playback processing
|
||||
static void BDMA_Channel0_IRQ_Handler(void) {
|
||||
__attribute__((section(".sram4"))) static uint16_t tx_buf[SOUND_TX_BUF_SIZE];
|
||||
|
||||
BDMA->IFCR |= BDMA_IFCR_CGIF0; // clear flag
|
||||
|
||||
// process samples (shift to 12b and bias to be unsigned)
|
||||
// since we are playing mono and receiving stereo, we take every other sample
|
||||
uint8_t buf_idx = (((BDMA_Channel0->CCR & BDMA_CCR_CT) >> BDMA_CCR_CT_Pos) == 1U) ? 0U : 1U;
|
||||
for (uint16_t i=0U; i < SOUND_RX_BUF_SIZE; i += 2U) {
|
||||
tx_buf[i/2U] = ((sound_rx_buf[buf_idx][i] + (1UL << 14)) >> 3);
|
||||
}
|
||||
|
||||
if (sound_idle_count == 0U) {
|
||||
current_board->set_amp_enabled(true);
|
||||
}
|
||||
sound_idle_count = 2U;
|
||||
|
||||
DMA1->LIFCR |= 0xF40;
|
||||
DMA1_Stream1->CR &= ~DMA_SxCR_EN;
|
||||
register_set(&DMA1_Stream1->M0AR, (uint32_t) tx_buf, 0xFFFFFFFFU);
|
||||
DMA1_Stream1->NDTR = SOUND_TX_BUF_SIZE;
|
||||
DMA1_Stream1->CR |= DMA_SxCR_EN;
|
||||
}
|
||||
|
||||
void sound_tick(void) {
|
||||
if (sound_idle_count > 0U) {
|
||||
sound_idle_count--;
|
||||
@@ -39,12 +14,46 @@ void sound_tick(void) {
|
||||
}
|
||||
}
|
||||
|
||||
// Playback processing
|
||||
static void BDMA_Channel0_IRQ_Handler(void) {
|
||||
__attribute__((section(".sram4"))) static uint16_t tx_buf[SOUND_TX_BUF_SIZE];
|
||||
|
||||
BDMA->IFCR |= BDMA_IFCR_CGIF0; // clear flag
|
||||
|
||||
uint8_t buf_idx = (((BDMA_Channel0->CCR & BDMA_CCR_CT) >> BDMA_CCR_CT_Pos) == 1U) ? 0U : 1U;
|
||||
|
||||
// process samples (shift to 12b and bias to be unsigned)
|
||||
bool sound_playing = false;
|
||||
for (uint16_t i=0U; i < SOUND_RX_BUF_SIZE; i += 2U) {
|
||||
// since we are playing mono and receiving stereo, we take every other sample
|
||||
tx_buf[i/2U] = ((sound_rx_buf[buf_idx][i] + (1UL << 14)) >> 3);
|
||||
if (sound_rx_buf[buf_idx][i] > 0U) {
|
||||
sound_playing = true;
|
||||
}
|
||||
}
|
||||
|
||||
// manage amp state
|
||||
if (sound_playing) {
|
||||
if (sound_idle_count == 0U) {
|
||||
current_board->set_amp_enabled(true);
|
||||
}
|
||||
sound_idle_count = 4U;
|
||||
}
|
||||
sound_tick();
|
||||
|
||||
DMA1->LIFCR |= 0xF40;
|
||||
DMA1_Stream1->CR &= ~DMA_SxCR_EN;
|
||||
register_set(&DMA1_Stream1->M0AR, (uint32_t) tx_buf, 0xFFFFFFFFU);
|
||||
DMA1_Stream1->NDTR = SOUND_TX_BUF_SIZE;
|
||||
DMA1_Stream1->CR |= DMA_SxCR_EN;
|
||||
}
|
||||
|
||||
void sound_init(void) {
|
||||
REGISTER_INTERRUPT(BDMA_Channel0_IRQn, BDMA_Channel0_IRQ_Handler, 64U, FAULT_INTERRUPT_RATE_SOUND_DMA)
|
||||
|
||||
// Init DAC
|
||||
register_set(&DAC1->MCR, 0U, 0xFFFFFFFFU);
|
||||
register_set(&DAC1->CR, DAC_CR_TEN1 | (6U << DAC_CR_TSEL1_Pos) | DAC_CR_DMAEN1, 0xFFFFFFFFU);
|
||||
register_set(&DAC1->CR, DAC_CR_TEN1 | (4U << DAC_CR_TSEL1_Pos) | DAC_CR_DMAEN1, 0xFFFFFFFFU);
|
||||
register_set_bits(&DAC1->CR, DAC_CR_EN1);
|
||||
|
||||
// Setup DMAMUX (DAC_CH1_DMA as input)
|
||||
@@ -55,13 +64,14 @@ void sound_init(void) {
|
||||
register_set(&DMA1_Stream1->FCR, 0U, 0x00000083U);
|
||||
DMA1_Stream1->CR = (0b11UL << DMA_SxCR_PL_Pos) | (0b01UL << DMA_SxCR_MSIZE_Pos) | (0b01UL << DMA_SxCR_PSIZE_Pos) | DMA_SxCR_MINC | (1U << DMA_SxCR_DIR_Pos);
|
||||
|
||||
// Init trigger timer (48kHz)
|
||||
register_set(&TIM7->PSC, 0U, 0xFFFFU);
|
||||
register_set(&TIM7->ARR, 2494U, 0xFFFFU);
|
||||
register_set(&TIM7->CR2, (0b10U << TIM_CR2_MMS_Pos), TIM_CR2_MMS_Msk);
|
||||
register_set(&TIM7->CR1, TIM_CR1_ARPE | TIM_CR1_URS, 0x088EU);
|
||||
TIM7->SR = 0U;
|
||||
TIM7->CR1 |= TIM_CR1_CEN;
|
||||
// Init trigger timer (little slower than 48kHz, pulled in sync by SAI4_FS_B)
|
||||
register_set(&TIM5->PSC, 2600U, 0xFFFFU);
|
||||
register_set(&TIM5->ARR, 100U, 0xFFFFFFFFU); // not important
|
||||
register_set(&TIM5->AF1, (0b0010UL << TIM5_AF1_ETRSEL_Pos), TIM5_AF1_ETRSEL_Msk);
|
||||
register_set(&TIM5->CR2, (0b010U << TIM_CR2_MMS_Pos), TIM_CR2_MMS_Msk);
|
||||
register_set(&TIM5->SMCR, TIM_SMCR_ECE | (0b00111UL << TIM_SMCR_TS_Pos)| (0b0100UL << TIM_SMCR_SMS_Pos), 0x31FFF7U);
|
||||
TIM5->CNT = 0U; TIM5->SR = 0U;
|
||||
TIM5->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
// stereo audio in
|
||||
register_set(&SAI4_Block_B->CR1, SAI_xCR1_DMAEN | (0b00UL << SAI_xCR1_SYNCEN_Pos) | (0b100U << SAI_xCR1_DS_Pos) | (0b11U << SAI_xCR1_MODE_Pos), 0x0FFB3FEFU);
|
||||
|
||||
@@ -31,7 +31,7 @@ def calculate_checksum(data):
|
||||
res ^= b
|
||||
return res
|
||||
|
||||
def pack_can_buffer(arr):
|
||||
def pack_can_buffer(arr, fd=False):
|
||||
snds = [b'']
|
||||
for address, dat, bus in arr:
|
||||
assert len(dat) in LEN_TO_DLC
|
||||
@@ -41,7 +41,7 @@ def pack_can_buffer(arr):
|
||||
data_len_code = LEN_TO_DLC[len(dat)]
|
||||
header = bytearray(CANPACKET_HEAD_SIZE)
|
||||
word_4b = address << 3 | extended << 2
|
||||
header[0] = (data_len_code << 4) | (bus << 1)
|
||||
header[0] = (data_len_code << 4) | (bus << 1) | int(fd)
|
||||
header[1] = word_4b & 0xFF
|
||||
header[2] = (word_4b >> 8) & 0xFF
|
||||
header[3] = (word_4b >> 16) & 0xFF
|
||||
@@ -808,6 +808,9 @@ class Panda:
|
||||
def set_canfd_non_iso(self, bus, non_iso):
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xfc, bus, int(non_iso), b'')
|
||||
|
||||
def set_canfd_auto(self, bus, auto):
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe8, bus, int(auto), b'')
|
||||
|
||||
def set_uart_baud(self, uart, rate):
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe4, uart, int(rate / 300), b'')
|
||||
|
||||
@@ -829,15 +832,15 @@ class Panda:
|
||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xc0, 0, 0, b'')
|
||||
|
||||
@ensure_can_packet_version
|
||||
def can_send_many(self, arr, timeout=CAN_SEND_TIMEOUT_MS):
|
||||
snds = pack_can_buffer(arr)
|
||||
def can_send_many(self, arr, *, fd=False, timeout=CAN_SEND_TIMEOUT_MS):
|
||||
snds = pack_can_buffer(arr, fd=fd)
|
||||
for tx in snds:
|
||||
while len(tx) > 0:
|
||||
bs = self._handle.bulkWrite(3, tx, timeout=timeout)
|
||||
tx = tx[bs:]
|
||||
|
||||
def can_send(self, addr, dat, bus, timeout=CAN_SEND_TIMEOUT_MS):
|
||||
self.can_send_many([[addr, dat, bus]], timeout=timeout)
|
||||
def can_send(self, addr, dat, bus, *, fd=False, timeout=CAN_SEND_TIMEOUT_MS):
|
||||
self.can_send_many([[addr, dat, bus]], fd=fd, timeout=timeout)
|
||||
|
||||
@ensure_can_packet_version
|
||||
def can_recv(self):
|
||||
|
||||
@@ -100,11 +100,14 @@ class PandaDFU:
|
||||
def st_serial_to_dfu_serial(st: str, mcu_type: McuType = McuType.F4):
|
||||
if st is None or st == "none":
|
||||
return None
|
||||
uid_base = struct.unpack("H" * 6, bytes.fromhex(st))
|
||||
if mcu_type == McuType.H7:
|
||||
return binascii.hexlify(struct.pack("!HHH", uid_base[1] + uid_base[5], uid_base[0] + uid_base[4], uid_base[3])).upper().decode("utf-8")
|
||||
else:
|
||||
return binascii.hexlify(struct.pack("!HHH", uid_base[1] + uid_base[5], uid_base[0] + uid_base[4] + 0xA, uid_base[3])).upper().decode("utf-8")
|
||||
try:
|
||||
uid_base = struct.unpack("H" * 6, bytes.fromhex(st))
|
||||
if mcu_type == McuType.H7:
|
||||
return binascii.hexlify(struct.pack("!HHH", uid_base[1] + uid_base[5], uid_base[0] + uid_base[4], uid_base[3])).upper().decode("utf-8")
|
||||
else:
|
||||
return binascii.hexlify(struct.pack("!HHH", uid_base[1] + uid_base[5], uid_base[0] + uid_base[4] + 0xA, uid_base[3])).upper().decode("utf-8")
|
||||
except struct.error:
|
||||
return None
|
||||
|
||||
def get_mcu_type(self) -> McuType:
|
||||
return self._mcu_type
|
||||
|
||||
@@ -402,7 +402,8 @@ class STBootloaderSPIHandle(BaseSTBootloaderHandle):
|
||||
|
||||
def get_chip_id(self) -> int:
|
||||
r = self._cmd(0x02, read_bytes=3)
|
||||
assert r[0] == 1 # response length - 1
|
||||
if r[0] != 1: # response length - 1
|
||||
raise PandaSpiException("incorrect response length")
|
||||
return ((r[1] << 8) + r[2])
|
||||
|
||||
def go_cmd(self, address: int) -> None:
|
||||
|
||||
@@ -12,7 +12,7 @@ ffi = FFI()
|
||||
|
||||
ffi.cdef("""
|
||||
typedef struct {
|
||||
unsigned char reserved : 1;
|
||||
unsigned char fd : 1;
|
||||
unsigned char bus : 3;
|
||||
unsigned char data_len_code : 4;
|
||||
unsigned char rejected : 1;
|
||||
|
||||
Reference in New Issue
Block a user