mirror of
https://github.com/google/pebble.git
synced 2025-07-04 22:00:38 -04:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
116
python_libs/pblprog/loader/src/irq_stm32f2_f4.def
Normal file
116
python_libs/pblprog/loader/src/irq_stm32f2_f4.def
Normal file
|
@ -0,0 +1,116 @@
|
|||
IRQ_DEF(0, WWDG) // Window WatchDog
|
||||
IRQ_DEF(1, PVD) // PVD through EXTI Line detection
|
||||
IRQ_DEF(2, TAMP_STAMP) // Tamper and TimeStamps through the EXTI line
|
||||
IRQ_DEF(3, RTC_WKUP) // RTC Wakeup through the EXTI line
|
||||
IRQ_DEF(4, FLASH) // FLASH
|
||||
IRQ_DEF(5, RCC) // RCC
|
||||
IRQ_DEF(6, EXTI0) // EXTI Line0
|
||||
IRQ_DEF(7, EXTI1) // EXTI Line1
|
||||
IRQ_DEF(8, EXTI2) // EXTI Line2
|
||||
IRQ_DEF(9, EXTI3) // EXTI Line3
|
||||
IRQ_DEF(10, EXTI4) // EXTI Line4
|
||||
IRQ_DEF(11, DMA1_Stream0) // DMA1 Stream 0
|
||||
IRQ_DEF(12, DMA1_Stream1) // DMA1 Stream 1
|
||||
IRQ_DEF(13, DMA1_Stream2) // DMA1 Stream 2
|
||||
IRQ_DEF(14, DMA1_Stream3) // DMA1 Stream 3
|
||||
IRQ_DEF(15, DMA1_Stream4) // DMA1 Stream 4
|
||||
IRQ_DEF(16, DMA1_Stream5) // DMA1 Stream 5
|
||||
IRQ_DEF(17, DMA1_Stream6) // DMA1 Stream 6
|
||||
IRQ_DEF(18, ADC) // ADC1, ADC2 and ADC3s
|
||||
IRQ_DEF(19, CAN1_TX) // CAN1 TX
|
||||
IRQ_DEF(20, CAN1_RX0) // CAN1 RX0
|
||||
IRQ_DEF(21, CAN1_RX1) // CAN1 RX1
|
||||
IRQ_DEF(22, CAN1_SCE) // CAN1 SCE
|
||||
IRQ_DEF(23, EXTI9_5) // External Line[9:5]s
|
||||
IRQ_DEF(24, TIM1_BRK_TIM9) // TIM1 Break and TIM9
|
||||
IRQ_DEF(25, TIM1_UP_TIM10) // TIM1 Update and TIM10
|
||||
IRQ_DEF(26, TIM1_TRG_COM_TIM11) // TIM1 Trigger and Commutation and TIM11
|
||||
IRQ_DEF(27, TIM1_CC) // TIM1 Capture Compare
|
||||
IRQ_DEF(28, TIM2) // TIM2
|
||||
IRQ_DEF(29, TIM3) // TIM3
|
||||
IRQ_DEF(30, TIM4) // TIM4
|
||||
IRQ_DEF(31, I2C1_EV) // I2C1 Event
|
||||
IRQ_DEF(32, I2C1_ER) // I2C1 Error
|
||||
IRQ_DEF(33, I2C2_EV) // I2C2 Event
|
||||
IRQ_DEF(34, I2C2_ER) // I2C2 Error
|
||||
IRQ_DEF(35, SPI1) // SPI1
|
||||
IRQ_DEF(36, SPI2) // SPI2
|
||||
IRQ_DEF(37, USART1) // USART1
|
||||
IRQ_DEF(38, USART2) // USART2
|
||||
IRQ_DEF(39, USART3) // USART3
|
||||
IRQ_DEF(40, EXTI15_10) // External Line[15:10]s
|
||||
IRQ_DEF(41, RTC_Alarm) // RTC Alarm (A and B) through EXTI Line
|
||||
IRQ_DEF(42, OTG_FS_WKUP) // USB OTG FS Wakeup through EXTI line
|
||||
IRQ_DEF(43, TIM8_BRK_TIM12) // TIM8 Break and TIM12
|
||||
IRQ_DEF(44, TIM8_UP_TIM13) // TIM8 Update and TIM13
|
||||
IRQ_DEF(45, TIM8_TRG_COM_TIM14) // TIM8 Trigger and Commutation and TIM14
|
||||
IRQ_DEF(46, TIM8_CC) // TIM8 Capture Compare
|
||||
IRQ_DEF(47, DMA1_Stream7) // DMA1 Stream7
|
||||
IRQ_DEF(48, FSMC) // FSMC
|
||||
IRQ_DEF(49, SDIO) // SDIO
|
||||
IRQ_DEF(50, TIM5) // TIM5
|
||||
IRQ_DEF(51, SPI3) // SPI3
|
||||
#if !defined(STM32F412xG)
|
||||
IRQ_DEF(52, UART4) // UART4
|
||||
IRQ_DEF(53, UART5) // UART5
|
||||
IRQ_DEF(54, TIM6_DAC) // TIM6 and DAC1&2 underrun errors
|
||||
#else
|
||||
IRQ_DEF(54, TIM6) // TIM6
|
||||
#endif
|
||||
IRQ_DEF(55, TIM7) // TIM7
|
||||
IRQ_DEF(56, DMA2_Stream0) // DMA2 Stream 0
|
||||
IRQ_DEF(57, DMA2_Stream1) // DMA2 Stream 1
|
||||
IRQ_DEF(58, DMA2_Stream2) // DMA2 Stream 2
|
||||
IRQ_DEF(59, DMA2_Stream3) // DMA2 Stream 3
|
||||
IRQ_DEF(60, DMA2_Stream4) // DMA2 Stream 4
|
||||
#if !defined(STM32F412xG)
|
||||
IRQ_DEF(61, ETH) // Ethernet
|
||||
IRQ_DEF(62, ETH_WKUP) // Ethernet Wakeup through EXTI line
|
||||
#else
|
||||
IRQ_DEF(61, DFSDM1) // DFSDM1
|
||||
IRQ_DEF(62, DFSDM2) // DFSDM2
|
||||
#endif
|
||||
IRQ_DEF(63, CAN2_TX) // CAN2 TX
|
||||
IRQ_DEF(64, CAN2_RX0) // CAN2 RX0
|
||||
IRQ_DEF(65, CAN2_RX1) // CAN2 RX1
|
||||
IRQ_DEF(66, CAN2_SCE) // CAN2 SCE
|
||||
IRQ_DEF(67, OTG_FS) // USB OTG FS
|
||||
IRQ_DEF(68, DMA2_Stream5) // DMA2 Stream 5
|
||||
IRQ_DEF(69, DMA2_Stream6) // DMA2 Stream 6
|
||||
IRQ_DEF(70, DMA2_Stream7) // DMA2 Stream 7
|
||||
IRQ_DEF(71, USART6) // USART6
|
||||
IRQ_DEF(72, I2C3_EV) // I2C3 event
|
||||
IRQ_DEF(73, I2C3_ER) // I2C3 error
|
||||
#if !defined(STM32F412xG)
|
||||
IRQ_DEF(74, OTG_HS_EP1_OUT) // USB OTG HS End Point 1 Out
|
||||
IRQ_DEF(75, OTG_HS_EP1_IN) // USB OTG HS End Point 1 In
|
||||
IRQ_DEF(76, OTG_HS_WKUP) // USB OTG HS Wakeup through EXTI
|
||||
IRQ_DEF(77, OTG_HS) // USB OTG HS
|
||||
IRQ_DEF(78, DCMI) // DCMI
|
||||
IRQ_DEF(79, CRYP) // CRYP crypto
|
||||
#endif
|
||||
#if !defined(STM32F412xG)
|
||||
IRQ_DEF(80, HASH_RNG) // Hash and Rng
|
||||
#else
|
||||
IRQ_DEF(80, RNG) // Rng
|
||||
#endif
|
||||
#if !defined(STM32F2XX) // STM32F2 IRQs end here
|
||||
IRQ_DEF(81, FPU) // FPU
|
||||
#if !defined(STM32F412xG)
|
||||
IRQ_DEF(82, UART7) // UART7
|
||||
IRQ_DEF(83, UART8) // UART8
|
||||
#endif
|
||||
IRQ_DEF(84, SPI4) // SPI4
|
||||
IRQ_DEF(85, SPI5) // SPI5
|
||||
#if !defined(STM32F412xG)
|
||||
IRQ_DEF(86, SPI6) // SPI6
|
||||
IRQ_DEF(87, SAI1) // SAI1
|
||||
IRQ_DEF(88, LTDC) // LTDC
|
||||
IRQ_DEF(89, LTDC_ER) // LTDC_ER
|
||||
IRQ_DEF(90, DMA2D) // DMA2D
|
||||
#else
|
||||
IRQ_DEF(92, QUADSPI) // QUADSPI
|
||||
IRQ_DEF(95, FMPI2C1_EV) // FMPI2C1 Event
|
||||
IRQ_DEF(96, FMPI2C1_ER) // FMPI2C1 Error
|
||||
#endif
|
||||
#endif // !defined(STM32F2XX)
|
112
python_libs/pblprog/loader/src/main.c
Normal file
112
python_libs/pblprog/loader/src/main.c
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define HEADER_ADDR (0x20000400)
|
||||
#define DATA_ADDR (0x20000800)
|
||||
#define FLASH_SR_ADDR (0x40023C0C)
|
||||
|
||||
#define STATE_WAITING (0)
|
||||
#define STATE_WRITE (1)
|
||||
#define STATE_CRC (2)
|
||||
|
||||
// typedef to make it easy to change the program size
|
||||
typedef uint8_t p_size_t;
|
||||
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint32_t state;
|
||||
volatile p_size_t *addr;
|
||||
uint32_t length;
|
||||
} Header;
|
||||
|
||||
static uint8_t prv_crc8(const uint8_t *data, uint32_t data_len) {
|
||||
uint8_t crc = 0;
|
||||
|
||||
// nibble lookup table for (x^8 + x^5 + x^3 + x^2 + x + 1)
|
||||
static const uint8_t lookup_table[] =
|
||||
{ 0, 47, 94, 113, 188, 147, 226, 205, 87, 120, 9, 38, 235, 196, 181, 154 };
|
||||
|
||||
for (uint32_t i = 0; i < data_len * 2; i++) {
|
||||
uint8_t nibble = data[i / 2];
|
||||
|
||||
if (i % 2 == 0) {
|
||||
nibble >>= 4;
|
||||
}
|
||||
|
||||
uint8_t index = nibble ^ (crc >> 4);
|
||||
crc = lookup_table[index & 0xf] ^ ((crc << 4) & 0xf0);
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
static void prv_wait_for_flash_not_busy(void) {
|
||||
while ((*(volatile uint32_t *)FLASH_SR_ADDR) & (1 << 16)); // BSY flag in FLASH_SR
|
||||
}
|
||||
|
||||
__attribute__((__noreturn__)) void Reset_Handler(void) {
|
||||
// Disable all interrupts
|
||||
__asm__("cpsid i" : : : "memory");
|
||||
|
||||
volatile uint32_t *flash_sr = (volatile uint32_t *)FLASH_SR_ADDR;
|
||||
volatile p_size_t *data = (volatile p_size_t *)DATA_ADDR;
|
||||
volatile Header *header = (volatile Header *)HEADER_ADDR;
|
||||
header->state = STATE_WAITING;
|
||||
|
||||
while(1) {
|
||||
switch (header->state) {
|
||||
case STATE_WRITE:
|
||||
prv_wait_for_flash_not_busy();
|
||||
for (uint32_t i = 0; i < header->length / sizeof(p_size_t); i++) {
|
||||
header->addr[i] = data[i];
|
||||
__asm__("isb 0xF":::"memory");
|
||||
__asm__("dsb 0xF":::"memory");
|
||||
/// Wait until flash isn't busy
|
||||
prv_wait_for_flash_not_busy();
|
||||
if (*flash_sr & (0x1f << 4)) {
|
||||
// error raised, set bad state
|
||||
header->state = *flash_sr;
|
||||
}
|
||||
if (header->addr[i] != data[i]) {
|
||||
header->state = 0xbd;
|
||||
}
|
||||
}
|
||||
header->addr += header->length / sizeof(p_size_t);
|
||||
header->state = STATE_WAITING;
|
||||
break;
|
||||
case STATE_CRC:
|
||||
*data = prv_crc8((uint8_t *)header->addr, header->length);
|
||||
header->state = STATE_WAITING;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
//! These symbols are defined in the linker script for use in initializing
|
||||
//! the data sections. uint8_t since we do arithmetic with section lengths.
|
||||
//! These are arrays to avoid the need for an & when dealing with linker symbols.
|
||||
extern uint8_t _estack[];
|
||||
|
||||
|
||||
__attribute__((__section__(".isr_vector"))) const void * const vector_table[] = {
|
||||
_estack,
|
||||
Reset_Handler
|
||||
};
|
136
python_libs/pblprog/loader/src/stm32f4_loader.ld
Normal file
136
python_libs/pblprog/loader/src/stm32f4_loader.ld
Normal file
|
@ -0,0 +1,136 @@
|
|||
__Stack_Size = 128;
|
||||
PROVIDE ( _Stack_Size = __Stack_Size ) ;
|
||||
|
||||
__Stack_Init = _estack - __Stack_Size ;
|
||||
PROVIDE ( _Stack_Init = __Stack_Init ) ;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 1K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, which goes to FLASH */
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} >RAM
|
||||
|
||||
/* for some STRx devices, the beginning of the startup code is stored in the .flashtext section, which goes to FLASH */
|
||||
.flashtext :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.flashtext) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} >RAM
|
||||
|
||||
/* Exception handling sections. "contains index entries for section unwinding" */
|
||||
.ARM.exidx :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.ARM.exidx)
|
||||
. = ALIGN(4);
|
||||
} >RAM
|
||||
|
||||
/* the program code is stored in the .text section, which goes to Flash */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
|
||||
*(.text) /* remaining code */
|
||||
*(.text.*) /* remaining code */
|
||||
*(.rodata) /* read-only data (constants) */
|
||||
*(.rodata*)
|
||||
*(.constdata) /* read-only data (constants) */
|
||||
*(.constdata*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(i.*)
|
||||
|
||||
. = ALIGN(4);
|
||||
} >RAM
|
||||
|
||||
/* This is the initialized data section
|
||||
The program executes knowing that the data is in the RAM
|
||||
but the loader puts the initial values in the FLASH (inidata).
|
||||
It is one task of the startup to copy the initial values from FLASH to RAM. */
|
||||
.data : {
|
||||
. = ALIGN(4);
|
||||
/* This is used by the startup in order to initialize the .data secion */
|
||||
__data_start = .;
|
||||
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
|
||||
. = ALIGN(4);
|
||||
__data_end = .; /* This is used by the startup in order to initialize the .data secion */
|
||||
} >RAM
|
||||
__data_load_start = LOADADDR(.data);
|
||||
|
||||
/* This is the uninitialized data section */
|
||||
.bss (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
__bss_start = .; /* This is used by the startup in order to initialize the .bss secion */
|
||||
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_end = .; /* This is used by the startup in order to initialize the .bss secion */
|
||||
} >RAM
|
||||
|
||||
.stack (NOLOAD) : {
|
||||
. = ALIGN(8);
|
||||
_sstack = .;
|
||||
. = . + __Stack_Size;
|
||||
. = ALIGN(8);
|
||||
_estack = .;
|
||||
} >RAM
|
||||
|
||||
/* after that it's only debugging information. */
|
||||
|
||||
/* remove the debugging information from the standard libraries */
|
||||
DISCARD : {
|
||||
libc.a ( * )
|
||||
libm.a ( * )
|
||||
libgcc.a ( * )
|
||||
}
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue