fixed PCB, add pre-alpha code

This commit is contained in:
Edward Emelianov 2024-12-26 12:24:15 +03:00
parent f26970392e
commit f1927c5437
55 changed files with 19476 additions and 11015 deletions

View File

@ -0,0 +1,9 @@
BINARY := canonusb
# MCU code
MCU ?= F103x6
# change this linking script depending on particular MCU model,
LDSCRIPT ?= stm32f103x6.ld
DEFINES := -DSTM32F10X_LD
include ../makefile.f1
include ../../makefile.stm32

111
F1:F103/Hall_linear/adc.c Normal file
View File

@ -0,0 +1,111 @@
/*
* This file is part of the hallinear project.
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#include "adc.h"
uint16_t ADC_array[ADC_CHANNELS*9];
void adc_setup(){
uint32_t ctr = 0;
// Enable clocking
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
__DSB();
// DMA configuration
DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR));
DMA1_Channel1->CMAR = (uint32_t)(ADC_array);
DMA1_Channel1->CNDTR = ADC_CHANNELS * 9;
DMA1_Channel1->CCR = DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0
| DMA_CCR_CIRC | DMA_CCR_PL | DMA_CCR_EN;
RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_ADCPRE)) | RCC_CFGR_ADCPRE_DIV8; // ADC clock = RCC / 8
// sampling time - 239.5 cycles for channels 0, 16 and 17
ADC1->SMPR2 = ADC_SMPR2_SMP0;
ADC1->SMPR1 = ADC_SMPR1_SMP16 | ADC_SMPR1_SMP17;
// sequence order: 7[0] -> 16[tsen] -> 17[vdd]
ADC1->SQR3 = (7 << 0) | (16<<5) | (17 << 10);
ADC1->SQR1 = (ADC_CHANNELS - 1) << 20; // amount of conversions
ADC1->CR1 = ADC_CR1_SCAN; // scan mode
// DMA, continuous mode; enable vref & Tsens; enable SWSTART as trigger
ADC1->CR2 = ADC_CR2_DMA | ADC_CR2_TSVREFE | ADC_CR2_CONT | ADC_CR2_EXTSEL | ADC_CR2_EXTTRIG;
// wake up ADC
ADC1->CR2 |= ADC_CR2_ADON;
__DSB();
// wait for Tstab - at least 1us
IWDG->KR = IWDG_REFRESH;
while(++ctr < 0xff) nop();
// calibration
ADC1->CR2 |= ADC_CR2_RSTCAL;
ctr = 0; while((ADC1->CR2 & ADC_CR2_RSTCAL) && ++ctr < 0xfffff) IWDG->KR = IWDG_REFRESH;
ADC1->CR2 |= ADC_CR2_CAL;
ctr = 0; while((ADC1->CR2 & ADC_CR2_CAL) && ++ctr < 0xfffff) IWDG->KR = IWDG_REFRESH;
// clear possible errors and start
ADC1->SR = 0;
ADC1->CR2 |= ADC_CR2_SWSTART;
}
/**
* @brief getADCval - calculate median value for `nch` channel
* @param nch - number of channel
* @return
*/
uint16_t getADCval(int nch){
int i, addr = nch;
#define PIX_SORT(a,b) { if ((a)>(b)) PIX_SWAP((a),(b)); }
#define PIX_SWAP(a,b) { register uint16_t temp=(a);(a)=(b);(b)=temp; }
uint16_t p[9];
for(i = 0; i < 9; ++i, addr += ADC_CHANNELS){ // first we should prepare array for optmed
p[i] = ADC_array[addr];
}
PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[6], p[7]) ;
PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
PIX_SORT(p[0], p[3]) ; PIX_SORT(p[5], p[8]) ; PIX_SORT(p[4], p[7]) ;
PIX_SORT(p[3], p[6]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[2], p[5]) ;
PIX_SORT(p[4], p[7]) ; PIX_SORT(p[4], p[2]) ; PIX_SORT(p[6], p[4]) ;
PIX_SORT(p[4], p[2]) ;
return p[4];
#undef PIX_SORT
#undef PIX_SWAP
}
// get voltage @input nch (1/100V)
uint32_t getADCvoltage(int nch){
uint32_t v = getADCval(nch);
v *= getVdd();
v /= 0xfff; // 12bit ADC
return v;
}
// return MCU temperature (degrees of celsius * 10)
int32_t getMCUtemp(){
// Temp = (V25 - Vsense)/Avg_Slope + 25
// V_25 = 1.45V, Slope = 4.3e-3
int32_t Vsense = getVdd() * getADCval(ADC_CH_TSEN);
int32_t temperature = 593920 - Vsense; // 593920 == 145*4096
temperature /= 172; // == /(4096*10*4.3e-3), 10 - to convert from *100 to *10
temperature += 250;
return(temperature);
}
// return Vdd * 100 (V)
uint32_t getVdd(){
uint32_t vdd = 120 * 4096; // 1.2V
vdd /= getADCval(ADC_CH_VDD);
return vdd;
}

41
F1:F103/Hall_linear/adc.h Normal file
View File

@ -0,0 +1,41 @@
/*
* This file is part of the hallinear project.
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#pragma once
#include <stm32f1.h>
// ADC channels in array
enum{
ADC_CH_0 = 0, // ADC input channels
ADC_CH_TSEN, // T sensor
ADC_CH_VDD, // Vdd sensor
ADC_CHANNELS
};
/**
* @brief ADC_array - array for ADC channels with median filtering
*/
extern uint16_t ADC_array[];
void adc_setup();
int32_t getMCUtemp();
uint32_t getVdd();
uint16_t getADCval(int nch);
uint32_t getADCvoltage(int nch);

240
F1:F103/Hall_linear/can.c Normal file
View File

@ -0,0 +1,240 @@
/*
* This file is part of the hallinear project.
* Copyright 2023 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#include <stm32f1.h>
#include <string.h> // memcpy
#include "can.h"
#include "flash.h" // can ID
#include "usb.h"
// REMAPPED to PB8/PB9!!!
// circular buffer for received messages
#define CANMESG_SZ ((int)sizeof(CAN_message))
#define INMESG_MAX ((int)((RBINSZ-1) / CANMESG_SZ))
#define OUTMESG_MAX ((int)((RBOUTSZ-1) / CANMESG_SZ))
static void can_process_fifo(uint8_t fifo_num);
// push next message into receive buffer; return 1 if buffer overfull
static int CAN_messagebuf_push(CAN_message *msg){
int l = RB_datalen((ringbuffer*)&rbin) / CANMESG_SZ;
if(l < 1){ // error or no free space
return 1;
}
if(RB_write((ringbuffer*)&rbin, (uint8_t*)msg, CANMESG_SZ) != CANMESG_SZ) return 1;
return 0;
}
// pop message from buffer
CAN_message *CAN_receive(){
static CAN_message msg;
if(CANMESG_SZ != RB_read((ringbuffer*)&rbin, (uint8_t*)&msg, CANMESG_SZ)) return NULL;
return &msg;
}
CAN_status CAN_send(CAN_message *msg){
if(!msg) return CAN_ERR;
int l = RB_datalen((ringbuffer*)&rbout) / CANMESG_SZ;
if(l < 1){ // error or no free space
return CAN_BUSY;
}
if(RB_write((ringbuffer*)&rbout, (uint8_t*)msg, CANMESG_SZ) != CANMESG_SZ) return 1;
return 0;
}
// speed - in kbps, ID - identificator (my ID or 0 as broadcast)
void CAN_setup(){
uint32_t speed = the_conf.canspeed;
if(speed < CAN_MIN_SPEED) speed = CAN_MIN_SPEED;
else if(speed > CAN_MAX_SPEED) speed = CAN_MAX_SPEED;
uint32_t tmout = 16000000;
// Configure GPIO: PB8 - CAN_Rx, PB9 - CAN_Tx
/* Select AF mode on PB8 and PB9 */
/* AF4 for CAN signals */
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPBEN;
AFIO->MAPR |= AFIO_MAPR_CAN_REMAP_REMAP2;
GPIOB->CRH = (GPIOB->CRH & ~(CRH(8,0xf)|CRH(9,0xf))) |
CRH(8, CNF_FLINPUT | MODE_INPUT) | CRH(9, CNF_AFPP | MODE_NORMAL);
/* Enable the peripheral clock CAN */
RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
CAN1->MCR |= CAN_MCR_INRQ;
while((CAN1->MSR & CAN_MSR_INAK) != CAN_MSR_INAK){
IWDG->KR = IWDG_REFRESH;
if(--tmout == 0) break;
}
CAN1->MCR &=~ CAN_MCR_SLEEP;
CAN1->MCR |= CAN_MCR_ABOM; /* allow automatically bus-off */
CAN1->BTR = (CAN_TBS2-1) << 20 | (CAN_TBS1-1) << 16 | (CAN_BIT_OSC/speed - 1); //| CAN_BTR_SILM | CAN_BTR_LBKM; /* (4) */
the_conf.canspeed = CAN_BIT_OSC/(uint32_t)((CAN1->BTR & CAN_BTR_BRP) + 1);
CAN1->MCR &= ~CAN_MCR_INRQ;
tmout = 16000000;
while((CAN1->MSR & CAN_MSR_INAK) == CAN_MSR_INAK){
IWDG->KR = IWDG_REFRESH;
if(--tmout == 0) break;
}
// accept only my ID
CAN1->FMR = CAN_FMR_FINIT;
CAN1->FM1R = CAN_FM1R_FBM0; // filter in list mode
CAN1->FA1R = CAN_FA1R_FACT0; // activate filter0:
CAN1->sFilterRegister[0].FR1 = the_conf.canID << 5;// My ID and 0
CAN1->FFA1R = 1; // filter 0 for FIFO1
CAN1->FMR &= ~CAN_FMR_FINIT;
CAN1->IER |= CAN_IER_ERRIE | CAN_IER_FOVIE1 | CAN_IER_BOFIE;
/* Configure IT */
NVIC_SetPriority(CAN1_RX1_IRQn, 2); // RX FIFO1 IRQ
NVIC_SetPriority(CAN1_SCE_IRQn, 2); // RX status changed IRQ
NVIC_EnableIRQ(CAN1_RX1_IRQn);
NVIC_EnableIRQ(CAN1_SCE_IRQn);
CAN1->MSR = 0; // clear SLAKI, WKUI, ERRI
}
void CAN_reinit(){
CAN1->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2;
RCC->APB1RSTR |= RCC_APB1RSTR_CAN1RST;
RCC->APB1RSTR &= ~RCC_APB1RSTR_CAN1RST;
CAN_setup(0);
}
static void try2send(){
CAN_message msg;
if(CANMESG_SZ != RB_read((ringbuffer*)&rbout, (uint8_t*)&msg, CANMESG_SZ)) return;
uint8_t mailbox = 0;
// check first free mailbox
if(CAN1->TSR & (CAN_TSR_TME)){
mailbox = (CAN1->TSR & CAN_TSR_CODE) >> 24;
}else{ // no free mailboxes
return;
}
CAN_TxMailBox_TypeDef *box = &CAN1->sTxMailBox[mailbox];
uint32_t lb = 0, hb = 0;
uint8_t *d = msg.data;
switch(msg.length){
case 8:
hb |= (uint32_t)d[7] << 24;
__attribute__((fallthrough));
case 7:
hb |= (uint32_t)d[6] << 16;
__attribute__((fallthrough));
case 6:
hb |= (uint32_t)d[5] << 8;
__attribute__((fallthrough));
case 5:
hb |= (uint32_t)d[4];
__attribute__((fallthrough));
case 4:
lb |= (uint32_t)d[3] << 24;
__attribute__((fallthrough));
case 3:
lb |= (uint32_t)d[2] << 16;
__attribute__((fallthrough));
case 2:
lb |= (uint32_t)d[1] << 8;
__attribute__((fallthrough));
default:
lb |= (uint32_t)d[0];
}
box->TDLR = lb;
box->TDHR = hb;
box->TDTR = msg.length;
box->TIR = (msg.ID & 0x7FF) << 21 | CAN_TI0R_TXRQ;
}
void CAN_proc(){
// check for messages in FIFO1
if(CAN1->RF1R & CAN_RF1R_FMP1){
can_process_fifo(1);
}
IWDG->KR = IWDG_REFRESH;
if(CAN1->ESR & (CAN_ESR_BOFF | CAN_ESR_EPVF | CAN_ESR_EWGF)){ // much errors - restart CAN BUS
// request abort for all mailboxes
CAN1->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2;
// reset CAN bus
RCC->APB1RSTR |= RCC_APB1RSTR_CAN1RST;
RCC->APB1RSTR &= ~RCC_APB1RSTR_CAN1RST;
CAN_reinit();
}
try2send(); // and try to send user data
}
static void can_process_fifo(uint8_t fifo_num){
if(fifo_num > 1) return;
CAN_FIFOMailBox_TypeDef *box = &CAN1->sFIFOMailBox[fifo_num];
volatile uint32_t *RFxR = (fifo_num) ? &CAN1->RF1R : &CAN1->RF0R;
// read all
while(*RFxR & CAN_RF0R_FMP0){ // amount of messages pending
// CAN_RDTxR: (16-31) - timestamp, (8-15) - filter match index, (0-3) - data length
/* TODO: check filter match index if more than one ID can receive */
CAN_message msg;
uint8_t *dat = msg.data;
uint8_t len = box->RDTR & 0x0f;
msg.length = len;
msg.ID = box->RIR >> 21;
if(len){ // message can be without data
uint32_t hb = box->RDHR, lb = box->RDLR;
switch(len){
case 8:
dat[7] = hb>>24;
__attribute__((fallthrough));
case 7:
dat[6] = (hb>>16) & 0xff;
__attribute__((fallthrough));
case 6:
dat[5] = (hb>>8) & 0xff;
__attribute__((fallthrough));
case 5:
dat[4] = hb & 0xff;
__attribute__((fallthrough));
case 4:
dat[3] = lb>>24;
__attribute__((fallthrough));
case 3:
dat[2] = (lb>>16) & 0xff;
__attribute__((fallthrough));
case 2:
dat[1] = (lb>>8) & 0xff;
__attribute__((fallthrough));
case 1:
dat[0] = lb & 0xff;
}
}
if(CAN_messagebuf_push(&msg)) return; // error: buffer is full, try later
*RFxR |= CAN_RF0R_RFOM0; // release fifo for access to next message
}
*RFxR = 0; // clear FOVR & FULL
}
void can_rx1_isr(){ // Rx FIFO1 (overrun)
if(CAN1->RF1R & CAN_RF1R_FOVR1){
CAN1->RF1R = CAN_RF1R_FOVR1;
}
}
void can_sce_isr(){ // status changed
if(CAN1->MSR & CAN_MSR_ERRI){ // Error
CAN1->MSR &= ~CAN_MSR_ERRI;
// request abort for problem mailbox
if(CAN1->TSR & CAN_TSR_TERR0) CAN1->TSR |= CAN_TSR_ABRQ0;
if(CAN1->TSR & CAN_TSR_TERR1) CAN1->TSR |= CAN_TSR_ABRQ1;
if(CAN1->TSR & CAN_TSR_TERR2) CAN1->TSR |= CAN_TSR_ABRQ2;
}
}

56
F1:F103/Hall_linear/can.h Normal file
View File

@ -0,0 +1,56 @@
/*
* This file is part of the hallinear project.
* Copyright 2023 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#pragma once
#include <stdint.h>
// CAN bus oscillator frequency: 36MHz
#define CAN_F_OSC (36000000UL)
// timing values TBS1 and TBS2 (in BTR [TBS1-1] and [TBS2-1])
// use 3 and 2 to get 6MHz
#define CAN_TBS1 (3)
#define CAN_TBS2 (2)
// bitrate oscillator frequency
#define CAN_BIT_OSC (CAN_F_OSC / (1+CAN_TBS1+CAN_TBS2))
#define CAN_MIN_SPEED (9600)
#define CAN_MAX_SPEED (3000000)
// CAN message
typedef struct{
uint8_t data[8]; // up to 8 bytes of data
uint8_t length; // data length
uint16_t ID; // ID of receiver
} CAN_message;
typedef enum{
CAN_STOP,
CAN_READY,
CAN_BUSY,
CAN_OK,
CAN_ERR,
CAN_FIFO_OVERRUN
} CAN_status;
void CAN_setup();
CAN_status CAN_send(CAN_message *msg);
void CAN_proc();
CAN_message *CAN_receive();
void CAN_reinit();

BIN
F1:F103/Hall_linear/canonusb.bin Executable file

Binary file not shown.

View File

@ -0,0 +1,218 @@
/*
* This file is part of the hallinear project.
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#include "adc.h"
#include "can.h"
#include "canproto.h"
#include "flash.h"
#include "hardware.h"
#include "strfunc.h"
#define FIXDL(m) do{m->length = 8;}while(0)
/*********** START of all common functions list (for `funclist`) ***********/
static errcodes ping(CAN_message _U_ *m){
return ERR_OK; // send same message
}
// reset MCU
static errcodes reset(CAN_message _U_ *msg){
NVIC_SystemReset();
return ERR_OK; // never reached
}
// get/set Tms
static errcodes time_get(CAN_message *msg){
FIXDL(msg);
MSGP_SET_U32(msg, Tms);
return ERR_OK;
}
// get MCU T
static errcodes mcut(CAN_message *msg){
FIXDL(msg);
MSGP_SET_U32(msg, getMCUtemp());
return ERR_OK;
}
// vdd
static errcodes vdd(CAN_message *msg){
FIXDL(msg);
MSGP_SET_U32(msg, getVdd());
return ERR_OK;
}
// get ADC value from AD0
static errcodes adcval(CAN_message *msg){
FIXDL(msg);
uint32_t U = getADCval(ADC_CH_0) * the_conf.Mul;
U /= the_conf.Div;
MSGP_SET_U32(msg, U);
return ERR_OK;
}
// get ADC raw values
static errcodes adcraw(CAN_message *msg){
FIXDL(msg);
uint8_t no = PARVAL(msg->data);
if(no >= ADC_CHANNELS) return ERR_BADPAR;
MSGP_SET_U32(msg, getADCval(no));
return ERR_OK;
}
// get ADC voltage from AD0
static errcodes adcvoltage(CAN_message *msg){
FIXDL(msg);
MSGP_SET_U32(msg, getADCvoltage(ADC_CH_0));
return ERR_OK;
}
// set common CAN ID / get CAN IN in
static errcodes canid(CAN_message *msg){
if(ISSETTER(msg->data)){
the_conf.canID = (uint16_t)MSGP_GET_U32(msg);
CAN_reinit(); // setup with new ID
}
FIXDL(msg);
MSGP_SET_U32(msg, the_conf.canID);
return ERR_OK;
}
// save config
static errcodes saveconf(CAN_message _U_ *msg){
if(0 == store_userconf()) return ERR_OK;
return ERR_CANTRUN;
}
// erase storage
static errcodes erasestor(CAN_message _U_ *msg){
if(0 == erase_storage(-1)) return ERR_OK;
return ERR_CANTRUN;
}
// common uint32_t setter/getter
static errcodes u32setget(CAN_message *msg){
uint16_t cmd = *(uint16_t*)msg->data;
uint32_t *ptr = NULL;
switch(cmd){
case CMD_CANSPEED:
ptr = &the_conf.canspeed;
if(ISSETTER(msg->data)){
*ptr = MSGP_GET_U32(msg);
CAN_reinit();
FIXDL(msg);
MSGP_SET_U32(msg, *ptr);
return ERR_OK;
}
break;
case CMD_DIV:
ptr = &the_conf.Div;
break;
case CMD_MUL:
ptr = &the_conf.Mul;
break;
default: break;
}
if(!ptr) return ERR_CANTRUN; // unknown error
if(ISSETTER(msg->data)){
*ptr = MSGP_GET_U32(msg);
}
FIXDL(msg);
MSGP_SET_U32(msg, *ptr);
return ERR_OK;
}
/************ END of all common functions list (for `funclist`) ************/
typedef struct{
errcodes (*fn)(CAN_message *msg); // function to run with can packet `msg`
int32_t minval; // minimal/maximal values of *(int32_t*)(&data[4]) - if minval != maxval
int32_t maxval;
uint8_t datalen; // minimal data length (full CAN packet, bytes)
} commonfunction;
// list of common (CAN/RS-232) functions
// !!!!!!!!! Getters should set message length to 8 !!!!!!!!!!!
static const commonfunction funclist[CMD_AMOUNT] = {
[CMD_PING] = {ping, 0, 0, 0},
[CMD_RESET] = {reset, 0, 0, 0},
[CMD_TIME] = {time_get, 0, 0, 0},
[CMD_MCUTEMP] = {mcut, 0, 0, 0},
[CMD_VDD] = {vdd, 0, 0, 0},
[CMD_ADC] = {adcval, 0, 0, 0},
[CMD_ADCRAW] = {adcraw, 0, 0, 3}, // need parno: 0..3
[CMD_ADCV] = {adcvoltage, 0, 0, 0},
[CMD_CANSPEED] = {u32setget, CAN_MIN_SPEED, CAN_MAX_SPEED, 0},
[CMD_CANID] = {canid, 1, 0x7ff, 0},
[CMD_DIV] = {u32setget, 1, INT32_MAX, 0},
[CMD_MUL] = {u32setget, 1, 1>>20, 0},
[CMD_SAVECONF] = {saveconf, 0, 0, 0},
[CMD_ERASESTOR] = {erasestor, 0, 0, 0},
};
/**
* FORMAT:
* 0 1 2 3 4 5 6 7
* [CMD][PAR][errcode][VALUE]
* CMD - uint16_t, PAR - uint8_t, errcode - one of `errcodes`, VALUE - int32_t
*/
/**
* @brief run_can_cmd - run common CAN/USB commands with limits checking
* @param msg - incoming message
*/
void run_can_cmd(CAN_message *msg){
uint8_t datalen = msg->length;
uint8_t *data = msg->data;
if(datalen < 2){
FORMERR(msg, ERR_WRONGLEN);
return;
}
uint16_t idx = *(uint16_t*)data;
if(idx >= CMD_AMOUNT || funclist[idx].fn == NULL){ // bad command index
FORMERR(msg, ERR_BADCMD); return;
}
// check minimal length
if(funclist[idx].datalen > datalen){
FORMERR(msg, ERR_WRONGLEN); return;
}
if(datalen > 3 && (data[2] & SETTER_FLAG)){
// check setter's length
if(datalen != 8){ FORMERR(msg, ERR_WRONGLEN); return; }
// check setter's values
if(funclist[idx].maxval != funclist[idx].minval){
int32_t newval = *(int32_t*)&data[4];
if(newval < funclist[idx].minval || newval > funclist[idx].maxval){
FORMERR(msg, ERR_BADVAL); return;
}
}
}
data[3] = funclist[idx].fn(msg); // set error field as result of function
data[2] &= ~SETTER_FLAG; // and clear setter flag
}
/**
* @brief parseCANcommand - parser
* @param msg - incoming message @ my CANID
* FORMAT:
* 0 1 2 3 4 5 6 7
* [CMD][PAR][errcode][VALUE]
* CMD - uint16_t, PAR - uint8_t, errcode - one of CAN_errcodes, VALUE - int32_t
* `errcode` of incoming message doesn't matter
* incoming data may have variable length
*/
void parseCANcommand(CAN_message *msg){
// check PING
if(msg->length != 0) run_can_cmd(msg);
uint32_t Tstart = Tms;
// send answer
while(Tms - Tstart < SEND_TIMEOUT_MS){
if(CAN_OK == CAN_send(msg)) return;
IWDG->KR = IWDG_REFRESH;
}
}

View File

@ -0,0 +1,87 @@
/*
* This file is part of the hallinear project.
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#pragma once
#include <stm32f1.h>
#include "can.h"
// command parameter flag means this is a setter
#define SETTER_FLAG (0x80)
#define ISSETTER(data) ((data[2] & SETTER_FLAG))
// parameter number 127 means there no parameter number at all (don't need paremeter or get all)
#define NO_PARNO (0x7f)
// base value of parameter (even if it is a setter)
#define PARBASE(x) (x & 0x7f)
// get parameter value of msg->data
#define PARVAL(data) (data[2] & 0x7f)
// make error for CAN answer
#define FORMERR(m, err) do{m->data[3] = err; if(m->length < 4) m->length = 4;}while(0)
#define SEND_TIMEOUT_MS (10)
// error codes for answer message
typedef enum{
ERR_OK, // 0 - all OK
ERR_BADPAR, // 1 - parameter is wrong
ERR_BADVAL, // 2 - wrong value
ERR_WRONGLEN, // 3 - wrong message length
ERR_BADCMD, // 4 - unknown command
ERR_CANTRUN, // 5 - can't run given command due to bad parameters or other
ERR_AMOUNT // amount of error codes
} errcodes;
// set command bytes in CAN message
#define MSG_SET_CMD(msg, cmd) do{*((uint16_t*)msg.data) = (cmd);}while(0)
#define MSGP_SET_CMD(msg, cmd) do{*((uint16_t*)msg->data) = (cmd);}while(0)
// set command parameter number
#define MSG_SET_PARNO(msg, n) do{msg.data[2] = (n);}while(0)
#define MSGP_SET_PARNO(msg, n) do{msg->data[2] = (n);}while(0)
// set error
#define MSG_SET_ERR(msg, err) do{msg.data[3] = (err);}while(0)
#define MSGP_SET_ERR(msg, err) do{msg->data[3] = (err);}while(0)
// set uint32_t data
#define MSG_SET_U32(msg, d) do{*((uint32_t*)(&msg.data[4])) = (d);}while(0)
#define MSGP_SET_U32(msg, d) do{*((uint32_t*)(&msg->data[4])) = (d);}while(0)
// get uint32_t data
#define MSG_GET_U32(msg) (*(uint32_t*)&msg.data[4])
#define MSGP_GET_U32(msg) (*(uint32_t*)&msg->data[4])
// CAN commands indexes
enum{
CMD_PING, // just ping
CMD_RESET, // reset MCU
CMD_TIME, // get Tms
CMD_MCUTEMP, // get MCU temperature (*10)
CMD_VDD, // get VDD
CMD_ADC, // (raw * Mul) / Div
CMD_ADCRAW, // get ADC raw values
CMD_ADCV, // ADC voltage (*100)
CMD_CANSPEED, // get/set CAN speed (kbps)
CMD_CANID, // get/set CAN ID
CMD_DIV, // get/set Div
CMD_MUL, // get/set Mul
CMD_SAVECONF, // save configuration
CMD_ERASESTOR, // erase all flash storage
// should be the last:
CMD_AMOUNT // amount of CAN commands
};
void run_can_cmd(CAN_message *msg);
void parseCANcommand(CAN_message *msg);

223
F1:F103/Hall_linear/flash.c Normal file
View File

@ -0,0 +1,223 @@
/*
* geany_encoding=koi8-r
* flash.c
*
* Copyright 2017 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#include "stm32f1.h"
#include "flash.h"
#include "strfunc.h"
#include "usb.h" // printout
#include <string.h> // memcpy
extern const uint32_t __varsstart, _BLOCKSIZE;
static const uint32_t FLASH_blocksize = (uint32_t)&_BLOCKSIZE;
static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here
// common structure for all datatypes stored
/*typedef struct {
uint16_t userconf_sz;
} flash_storage;*/
#define USERCONF_INITIALIZER { \
.userconf_sz = sizeof(user_conf) \
,.canspeed = 250 \
,.canID = 1 \
,.Div = 1 \
,.Mul = 1 \
}
static int write2flash(const void*, const void*, uint32_t);
const user_conf *Flash_Data = (const user_conf *)(&__varsstart);
user_conf the_conf = USERCONF_INITIALIZER;
static int currentconfidx = -1; // index of current configuration
/**
* @brief binarySearch - binary search in flash for last non-empty cell
* any struct searched should have its sizeof() @ the first field!!!
* @param l - left index
* @param r - right index (should be @1 less than last index!)
* @param start - starting address
* @param stor_size - size of structure to search
* @return index of non-empty cell or -1
*/
static int binarySearch(int r, const uint8_t *start, int stor_size){
int l = 0;
while(r >= l){
int mid = l + (r - l) / 2;
#ifdef EBUG
USB_sendstr("mid/l/r=");
USB_sendstr(u2str(mid)); USB_sendstr("/");
USB_sendstr(u2str(l)); USB_sendstr("/");
USB_sendstr(u2str(r)); USB_sendstr("/");
newline();
#endif
const uint8_t *s = start + mid * stor_size;
if(*((const uint16_t*)s) == stor_size){
if(*((const uint16_t*)(s + stor_size)) == 0xffff){ // next is free
return mid;
}else{ // element is to the right
l = mid + 1;
}
}else{ // element is to the left
r = mid - 1;
}
}
return -1; // not found
}
/**
* @brief flashstorage_init - initialization of user conf storage
* run in once @ start
*/
void flashstorage_init(){
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
uint32_t flsz = FLASH_SIZE * 1024; // size in bytes
flsz -= (uint32_t)(&__varsstart) - FLASH_BASE;
maxCnum = flsz / sizeof(user_conf);
}
#ifdef EBUG
USB_sendstr("INIT\n");
#endif
// -1 if there's no data at all & flash is clear; maxnum-1 if flash is full
currentconfidx = binarySearch((int)maxCnum-2, (const uint8_t*)Flash_Data, sizeof(user_conf));
if(currentconfidx > -1){
memcpy(&the_conf, &Flash_Data[currentconfidx], sizeof(user_conf));
}
#ifdef EBUG
USB_sendstr("currentconfidx="); USB_sendstr(u2str(currentconfidx)); newline();
#endif
}
// store new configuration
// @return 0 if all OK
int store_userconf(){
// maxnum - 3 means that there always should be at least one empty record after last data
// for binarySearch() checking that there's nothing more after it!
if(currentconfidx > (int)maxCnum - 3){ // there's no more place
currentconfidx = 0;
if(erase_storage(-1)) return 1;
}else ++currentconfidx; // take next data position (0 - within first run after firmware flashing)
return write2flash((const void*)&Flash_Data[currentconfidx], &the_conf, sizeof(the_conf));
}
static int write2flash(const void *start, const void *wrdata, uint32_t stor_size){
int ret = 0;
if (FLASH->CR & FLASH_CR_LOCK){ // unloch flash
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
}
while (FLASH->SR & FLASH_SR_BSY) IWDG->KR = IWDG_REFRESH;
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPRTERR; // clear all flags
FLASH->CR |= FLASH_CR_PG;
const uint16_t *data = (const uint16_t*) wrdata;
volatile uint16_t *address = (volatile uint16_t*) start;
uint32_t i, count = (stor_size + 1) / 2;
for(i = 0; i < count; ++i){
*(volatile uint16_t*)(address + i) = data[i];
while(FLASH->SR & FLASH_SR_BSY) IWDG->KR = IWDG_REFRESH;
if(*(volatile uint16_t*)(address + i) != data[i]){
USB_sendstr("DON'T MATCH!\n");
ret = 1;
break;
}
if(FLASH->SR & FLASH_SR_PGERR){
USB_sendstr("Prog err\n");
ret = 1; // program error - meet not 0xffff
break;
}
#ifdef EBUG
USB_sendstr(u2str(stor_size)); USB_sendstr("bytes stored @0x");
USB_sendstr(uhex2str((uint32_t)(address + i))); newline();
#endif
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPRTERR;
}
FLASH->CR &= ~(FLASH_CR_PG);
return ret;
}
// erase Nth page of flash storage (flash should be prepared!)
static int erase_pageN(int N){
int ret = 0;
#ifdef EBUG
USB_sendstr("Erase page #"); USB_sendstr(u2str(N)); newline();
#endif
FLASH->AR = (uint32_t)Flash_Data + N*FLASH_blocksize;
FLASH->CR |= FLASH_CR_STRT;
while(FLASH->SR & FLASH_SR_BSY) IWDG->KR = IWDG_REFRESH;
FLASH->SR = FLASH_SR_EOP;
if(FLASH->SR & FLASH_SR_WRPRTERR){ /* Check Write protection error */
ret = 1;
FLASH->SR = FLASH_SR_WRPRTERR; /* Clear the flag by software by writing it at 1*/
}
return ret;
}
// erase full storage (npage < 0) or its nth page; @return 0 if all OK
int erase_storage(int npage){
int ret = 0;
uint32_t end = 1, start = 0, flsz = 0;
if(FLASH_SIZE > 0 && FLASH_SIZE < 20000){
flsz = FLASH_SIZE * 1024; // size in bytes
flsz -= (uint32_t)Flash_Data - FLASH_BASE;
}
end = flsz / FLASH_blocksize;
#ifdef EBUG
USB_sendstr("FLASH_SIZE="); USB_sendstr(u2str(FLASH_SIZE));
USB_sendstr("\nflsz="); USB_sendstr(u2str(flsz));
USB_sendstr("\nend="); USB_sendstr(u2str(end));
USB_sendstr("\ncurrentconfidx="); USB_sendstr(u2str(currentconfidx));
USB_sendstr("\nmaxCnum="); USB_sendstr(u2str(maxCnum));
newline();
#endif
if(end == 0 || end >= FLASH_SIZE) return 1;
if(npage > -1){ // erase only one page
if((uint32_t)npage >= end) return 1;
start = npage;
end = start + 1;
}
if((FLASH->CR & FLASH_CR_LOCK) != 0){
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
}
while(FLASH->SR & FLASH_SR_BSY) IWDG->KR = IWDG_REFRESH;
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPRTERR;
FLASH->CR |= FLASH_CR_PER;
for(uint32_t i = start; i < end; ++i){
if(erase_pageN(i)){
ret = 1;
break;
}
}
FLASH->CR &= ~FLASH_CR_PER;
return ret;
}
void dump_userconf(){
USB_sendstr("userconf_sz="); printu(the_conf.userconf_sz);
USB_sendstr("\ncurrentconfidx="); printu(currentconfidx);
USB_sendstr("\nCAN_speed="); printu(the_conf.canspeed);
USB_sendstr("\nCAN_ID="); printu(the_conf.canID);
USB_sendstr("\nDiv="); printu(the_conf.Div);
USB_sendstr("\nMul="); printu(the_conf.Mul);
newline();
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of the hallinear project.
* Copyright 2023 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#pragma once
#include <stm32f1.h>
#define FLASH_SIZE_REG ((uint32_t)0x1FFFF7E0)
#define FLASH_SIZE *((uint16_t*)FLASH_SIZE_REG)
/*
* struct to save user configurations
*/
typedef struct __attribute__((packed, aligned(4))){
uint16_t userconf_sz; // "magick number"
uint16_t canID; // CAN bus device ID
uint32_t canspeed; // CAN bus speed
uint32_t Div; // ADC val = (Raw * Mul) / Div
uint32_t Mul; // should be less than 2^20!!!
} user_conf;
extern user_conf the_conf;
void flashstorage_init();
int store_userconf();
int erase_storage(int npage);
void dump_userconf();

View File

@ -0,0 +1 @@
-std=c17

View File

@ -0,0 +1,6 @@
// Add predefined macros for your project here. For example:
// #define THE_ANSWER 42
#define EBUG
#define STM32F1
#define STM32F103x8
#define STM32F10X_LD

View File

@ -0,0 +1 @@
[General]

View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 6.0.0, 2022-09-07T10:47:24. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{cf63021e-ef53-49b0-b03b-2f2570cdf3b6}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">KOI8-R</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">false</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">1</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">2</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">true</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="ClangTools">
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">4</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
</valuemap>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{91347f2c-5221-46a7-80b1-0a054ca02f79}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/eddy/Docs/SAO/ELECTRONICS/STM32/F1-srcs/USB_SPI</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Очистка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Очистка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Развёртывание</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Развёртывание</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

View File

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.12.3, 2022-05-28T23:21:45. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{7bd84e39-ca37-46d3-be9d-99ebea85bc0d}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">KOI8-R</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">false</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{65a14f9e-e008-4c1b-89df-4eaa4774b6e3}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Big/Data/00__Electronics/STM32/F303-nolib/blink</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">true</value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Очистка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Очистка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Default</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Развёртывание</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Развёртывание</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="bool" key="RunConfiguration.Arguments.multi">false</value>
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

View File

@ -0,0 +1 @@
-std=c++17

View File

@ -0,0 +1,27 @@
adc.c
adc.h
can.c
can.h
canon.c
canon.h
canproto.c
canproto.h
flash.c
flash.h
hardware.c
hardware.h
main.c
proto.c
proto.h
ringbuffer.c
ringbuffer.h
spi.c
spi.h
strfunc.c
strfunc.h
usb.c
usb.h
usb_lib.c
usb_lib.h
usbhw.c
usbhw.h

View File

@ -0,0 +1,6 @@
.
../inc
../inc/Fx
../inc/cm
../inc/ld
../inc/startup

View File

@ -0,0 +1,55 @@
/*
* This file is part of the hallinear project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#include "hardware.h"
#ifndef EBUG
TRUE_INLINE void iwdg_setup(){
uint32_t tmout = 16000000;
RCC->CSR |= RCC_CSR_LSION;
while((RCC->CSR & RCC_CSR_LSIRDY) != RCC_CSR_LSIRDY){if(--tmout == 0) break;} /* (2) */
IWDG->KR = IWDG_START;
IWDG->KR = IWDG_WRITE_ACCESS;
IWDG->PR = IWDG_PR_PR_1;
IWDG->RLR = 1250;
tmout = 16000000;
while(IWDG->SR){if(--tmout == 0) break;}
IWDG->KR = IWDG_REFRESH;
}
#endif
TRUE_INLINE void gpio_setup(){
// Set APB2 clock to 72/4=18MHz
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_PPRE2) | RCC_CFGR_PPRE2_DIV4;
// Enable clocks to the GPIO subsystems
RCC->APB2ENR = RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN;
AFIO->MAPR = AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // for PA15 - USB pullup
// PA3 - jumper (pullup in), PA7 - ADC in
GPIOA->CRL = 1<<3;
GPIOA->CRL = CRL(3, CNF_PUDINPUT | MODE_INPUT) | CRL(7, CNF_ANALOG|MODE_INPUT);
USBPU_OFF();
GPIOA->CRH = CRH(15, CNF_PPOUTPUT | MODE_SLOW);
}
void hw_setup(){
gpio_setup();
#ifndef EBUG
iwdg_setup();
#endif
}

View File

@ -0,0 +1,36 @@
/*
* This file is part of the hallinear project.
* Copyright 2023 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#pragma once
#include <stm32f1.h>
// USB DP pullup: PA15
#define USBPU_port GPIOA
#define USBPU_pin (1<<15)
#define USBPU_ON() pin_clear(USBPU_port, USBPU_pin)
#define USBPU_OFF() pin_set(USBPU_port, USBPU_pin)
// CAN-USB switch: PA3, pullup
#define USBCAN_port GPIOA
#define USBCAN_pin (1<<3)
#define ISUSB() (0 == (USBCAN_port->IDR & USBCAN_pin))
extern volatile uint32_t Tms;
void hw_setup();

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"board": {
"active_layer": 36,
"active_layer": 0,
"active_layer_preset": "",
"auto_track_width": false,
"hidden_netclasses": [],

View File

@ -37,9 +37,9 @@
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 1.5,
"height": 2.0,
"width": 2.0
"drill": 0.0,
"height": 0.3,
"width": 0.3
},
"silk_line_width": 0.15,
"silk_text_italic": false,
@ -49,7 +49,7 @@
"silk_text_upright": false,
"zones": {
"45_degree_only": false,
"min_clearance": 0.508
"min_clearance": 0.25
}
},
"diff_pair_dimensions": [

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
%TF.GenerationSoftware,KiCad,Pcbnew,8.0.6*%
%TF.CreationDate,2024-12-19T11:27:53+03:00*%
%TF.CreationDate,2024-12-26T12:17:48+03:00*%
%TF.ProjectId,Hall,48616c6c-2e6b-4696-9361-645f70636258,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Soldermask,Bot*%
%TF.FilePolarity,Negative*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-19 11:27:53*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-26 12:17:48*
%MOMM*%
%LPD*%
G01*
@ -47,51 +47,51 @@ G04 Aperture macros list*
0 Add horizontal line*
21,1,$1,$2,0,0,$3*%
G04 Aperture macros list end*
%ADD10C,3.200000*%
%ADD11R,1.700000X1.700000*%
%ADD12O,1.700000X1.700000*%
%ADD13RoundRect,0.250001X-0.799999X-0.799999X0.799999X-0.799999X0.799999X0.799999X-0.799999X0.799999X0*%
%ADD14C,0.650000*%
%ADD15O,1.000000X2.100000*%
%ADD16O,1.000000X1.600000*%
%ADD10C,0.650000*%
%ADD11O,1.000000X2.100000*%
%ADD12O,1.000000X1.600000*%
%ADD13C,3.200000*%
%ADD14R,1.700000X1.700000*%
%ADD15O,1.700000X1.700000*%
%ADD16RoundRect,0.250001X-0.799999X-0.799999X0.799999X-0.799999X0.799999X0.799999X-0.799999X0.799999X0*%
%ADD17RotRect,1.000000X1.000000X25.000000*%
%ADD18HorizOval,1.000000X0.000000X0.000000X0.000000X0.000000X0*%
G04 APERTURE END LIST*
D10*
%TO.C,J6*%
X67110000Y-66695000D03*
X72890000Y-66695000D03*
D11*
X65680000Y-66165000D03*
D12*
X65680000Y-70345000D03*
D11*
X74320000Y-66165000D03*
D12*
X74320000Y-70345000D03*
%TD*%
D13*
%TO.C,H3*%
X60444919Y-66632809D03*
%TD*%
D11*
D14*
%TO.C,J3*%
X61500000Y-46500000D03*
D12*
D15*
X61500000Y-49040000D03*
X61500000Y-51580000D03*
%TD*%
D13*
D16*
%TO.C,J4*%
X77216000Y-68376800D03*
%TD*%
%TO.C,J5*%
X65405000Y-28575000D03*
X65405000Y-28321000D03*
%TD*%
%TO.C,J2*%
X64363600Y-61823600D03*
X63627000Y-61468000D03*
%TD*%
D14*
%TO.C,J6*%
X67110000Y-66695000D03*
X72890000Y-66695000D03*
D15*
X65680000Y-66165000D03*
D16*
X65680000Y-70345000D03*
D15*
X74320000Y-66165000D03*
D16*
X74320000Y-70345000D03*
%TD*%
D10*
D13*
%TO.C,H1*%
X60445087Y-31467095D03*
%TD*%

View File

@ -1,12 +1,12 @@
%TF.GenerationSoftware,KiCad,Pcbnew,8.0.6*%
%TF.CreationDate,2024-12-19T11:27:53+03:00*%
%TF.CreationDate,2024-12-26T12:17:47+03:00*%
%TF.ProjectId,Hall,48616c6c-2e6b-4696-9361-645f70636258,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Paste,Bot*%
%TF.FilePolarity,Positive*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-19 11:27:53*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-26 12:17:47*
%MOMM*%
%LPD*%
G01*

View File

@ -1,12 +1,12 @@
%TF.GenerationSoftware,KiCad,Pcbnew,8.0.6*%
%TF.CreationDate,2024-12-19T11:27:53+03:00*%
%TF.CreationDate,2024-12-26T12:17:48+03:00*%
%TF.ProjectId,Hall,48616c6c-2e6b-4696-9361-645f70636258,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Legend,Bot*%
%TF.FilePolarity,Positive*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-19 11:27:53*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-26 12:17:48*
%MOMM*%
%LPD*%
G01*
@ -16,6 +16,284 @@ G04 APERTURE LIST*
%ADD12C,0.120000*%
G04 APERTURE END LIST*
D10*
X87020400Y-37998400D02*
X86868000Y-38862000D01*
X86207600Y-38252400D02*
X87020400Y-37998400D01*
X85598000Y-39674800D02*
X87020400Y-37998400D01*
X71345201Y-44393662D02*
X70869011Y-46393662D01*
X70869011Y-46393662D02*
X70488058Y-44965090D01*
X70488058Y-44965090D02*
X70107106Y-46393662D01*
X70107106Y-46393662D02*
X69630916Y-44393662D01*
X68869011Y-46393662D02*
X68869011Y-44393662D01*
X68011868Y-46393662D02*
X68011868Y-45346043D01*
X68011868Y-45346043D02*
X68107106Y-45155566D01*
X68107106Y-45155566D02*
X68297582Y-45060328D01*
X68297582Y-45060328D02*
X68583297Y-45060328D01*
X68583297Y-45060328D02*
X68773773Y-45155566D01*
X68773773Y-45155566D02*
X68869011Y-45250804D01*
X67059487Y-46393662D02*
X67059487Y-45060328D01*
X67059487Y-44393662D02*
X67154725Y-44488900D01*
X67154725Y-44488900D02*
X67059487Y-44584138D01*
X67059487Y-44584138D02*
X66964249Y-44488900D01*
X66964249Y-44488900D02*
X67059487Y-44393662D01*
X67059487Y-44393662D02*
X67059487Y-44584138D01*
X66392820Y-45060328D02*
X65630916Y-45060328D01*
X66107106Y-44393662D02*
X66107106Y-46107947D01*
X66107106Y-46107947D02*
X66011868Y-46298424D01*
X66011868Y-46298424D02*
X65821392Y-46393662D01*
X65821392Y-46393662D02*
X65630916Y-46393662D01*
X64202344Y-46298424D02*
X64392820Y-46393662D01*
X64392820Y-46393662D02*
X64773773Y-46393662D01*
X64773773Y-46393662D02*
X64964249Y-46298424D01*
X64964249Y-46298424D02*
X65059487Y-46107947D01*
X65059487Y-46107947D02*
X65059487Y-45346043D01*
X65059487Y-45346043D02*
X64964249Y-45155566D01*
X64964249Y-45155566D02*
X64773773Y-45060328D01*
X64773773Y-45060328D02*
X64392820Y-45060328D01*
X64392820Y-45060328D02*
X64202344Y-45155566D01*
X64202344Y-45155566D02*
X64107106Y-45346043D01*
X64107106Y-45346043D02*
X64107106Y-45536519D01*
X64107106Y-45536519D02*
X65059487Y-45726995D01*
X70488058Y-48565931D02*
X70202344Y-48661169D01*
X70202344Y-48661169D02*
X70107106Y-48756407D01*
X70107106Y-48756407D02*
X70011868Y-48946883D01*
X70011868Y-48946883D02*
X70011868Y-49232597D01*
X70011868Y-49232597D02*
X70107106Y-49423073D01*
X70107106Y-49423073D02*
X70202344Y-49518312D01*
X70202344Y-49518312D02*
X70392820Y-49613550D01*
X70392820Y-49613550D02*
X71154725Y-49613550D01*
X71154725Y-49613550D02*
X71154725Y-47613550D01*
X71154725Y-47613550D02*
X70488058Y-47613550D01*
X70488058Y-47613550D02*
X70297582Y-47708788D01*
X70297582Y-47708788D02*
X70202344Y-47804026D01*
X70202344Y-47804026D02*
X70107106Y-47994502D01*
X70107106Y-47994502D02*
X70107106Y-48184978D01*
X70107106Y-48184978D02*
X70202344Y-48375454D01*
X70202344Y-48375454D02*
X70297582Y-48470692D01*
X70297582Y-48470692D02*
X70488058Y-48565931D01*
X70488058Y-48565931D02*
X71154725Y-48565931D01*
X69154725Y-49613550D02*
X69154725Y-48280216D01*
X69154725Y-48661169D02*
X69059487Y-48470692D01*
X69059487Y-48470692D02*
X68964249Y-48375454D01*
X68964249Y-48375454D02*
X68773773Y-48280216D01*
X68773773Y-48280216D02*
X68583296Y-48280216D01*
X67630916Y-49613550D02*
X67821392Y-49518312D01*
X67821392Y-49518312D02*
X67916630Y-49423073D01*
X67916630Y-49423073D02*
X68011868Y-49232597D01*
X68011868Y-49232597D02*
X68011868Y-48661169D01*
X68011868Y-48661169D02*
X67916630Y-48470692D01*
X67916630Y-48470692D02*
X67821392Y-48375454D01*
X67821392Y-48375454D02*
X67630916Y-48280216D01*
X67630916Y-48280216D02*
X67345201Y-48280216D01*
X67345201Y-48280216D02*
X67154725Y-48375454D01*
X67154725Y-48375454D02*
X67059487Y-48470692D01*
X67059487Y-48470692D02*
X66964249Y-48661169D01*
X66964249Y-48661169D02*
X66964249Y-49232597D01*
X66964249Y-49232597D02*
X67059487Y-49423073D01*
X67059487Y-49423073D02*
X67154725Y-49518312D01*
X67154725Y-49518312D02*
X67345201Y-49613550D01*
X67345201Y-49613550D02*
X67630916Y-49613550D01*
X66297582Y-48280216D02*
X65916630Y-49613550D01*
X65916630Y-49613550D02*
X65535677Y-48661169D01*
X65535677Y-48661169D02*
X65154725Y-49613550D01*
X65154725Y-49613550D02*
X64773773Y-48280216D01*
X64011868Y-48280216D02*
X64011868Y-49613550D01*
X64011868Y-48470692D02*
X63916630Y-48375454D01*
X63916630Y-48375454D02*
X63726154Y-48280216D01*
X63726154Y-48280216D02*
X63440439Y-48280216D01*
X63440439Y-48280216D02*
X63249963Y-48375454D01*
X63249963Y-48375454D02*
X63154725Y-48565931D01*
X63154725Y-48565931D02*
X63154725Y-49613550D01*
X70107106Y-50928676D02*
X70297582Y-50833438D01*
X70297582Y-50833438D02*
X70583296Y-50833438D01*
X70583296Y-50833438D02*
X70869011Y-50928676D01*
X70869011Y-50928676D02*
X71059487Y-51119152D01*
X71059487Y-51119152D02*
X71154725Y-51309628D01*
X71154725Y-51309628D02*
X71249963Y-51690580D01*
X71249963Y-51690580D02*
X71249963Y-51976295D01*
X71249963Y-51976295D02*
X71154725Y-52357247D01*
X71154725Y-52357247D02*
X71059487Y-52547723D01*
X71059487Y-52547723D02*
X70869011Y-52738200D01*
X70869011Y-52738200D02*
X70583296Y-52833438D01*
X70583296Y-52833438D02*
X70392820Y-52833438D01*
X70392820Y-52833438D02*
X70107106Y-52738200D01*
X70107106Y-52738200D02*
X70011868Y-52642961D01*
X70011868Y-52642961D02*
X70011868Y-51976295D01*
X70011868Y-51976295D02*
X70392820Y-51976295D01*
X69154725Y-52833438D02*
X69154725Y-51500104D01*
X69154725Y-51881057D02*
X69059487Y-51690580D01*
X69059487Y-51690580D02*
X68964249Y-51595342D01*
X68964249Y-51595342D02*
X68773773Y-51500104D01*
X68773773Y-51500104D02*
X68583296Y-51500104D01*
X67154725Y-52738200D02*
X67345201Y-52833438D01*
X67345201Y-52833438D02*
X67726154Y-52833438D01*
X67726154Y-52833438D02*
X67916630Y-52738200D01*
X67916630Y-52738200D02*
X68011868Y-52547723D01*
X68011868Y-52547723D02*
X68011868Y-51785819D01*
X68011868Y-51785819D02*
X67916630Y-51595342D01*
X67916630Y-51595342D02*
X67726154Y-51500104D01*
X67726154Y-51500104D02*
X67345201Y-51500104D01*
X67345201Y-51500104D02*
X67154725Y-51595342D01*
X67154725Y-51595342D02*
X67059487Y-51785819D01*
X67059487Y-51785819D02*
X67059487Y-51976295D01*
X67059487Y-51976295D02*
X68011868Y-52166771D01*
X65440439Y-52738200D02*
X65630915Y-52833438D01*
X65630915Y-52833438D02*
X66011868Y-52833438D01*
X66011868Y-52833438D02*
X66202344Y-52738200D01*
X66202344Y-52738200D02*
X66297582Y-52547723D01*
X66297582Y-52547723D02*
X66297582Y-51785819D01*
X66297582Y-51785819D02*
X66202344Y-51595342D01*
X66202344Y-51595342D02*
X66011868Y-51500104D01*
X66011868Y-51500104D02*
X65630915Y-51500104D01*
X65630915Y-51500104D02*
X65440439Y-51595342D01*
X65440439Y-51595342D02*
X65345201Y-51785819D01*
X65345201Y-51785819D02*
X65345201Y-51976295D01*
X65345201Y-51976295D02*
X66297582Y-52166771D01*
X64488058Y-51500104D02*
X64488058Y-52833438D01*
X64488058Y-51690580D02*
X64392820Y-51595342D01*
X64392820Y-51595342D02*
X64202344Y-51500104D01*
X64202344Y-51500104D02*
X63916629Y-51500104D01*
X63916629Y-51500104D02*
X63726153Y-51595342D01*
X63726153Y-51595342D02*
X63630915Y-51785819D01*
X63630915Y-51785819D02*
X63630915Y-52833438D01*
X85664439Y-40952520D02*
X85664439Y-40152520D01*
X85664439Y-40152520D02*
@ -550,12 +828,6 @@ X82083486Y-47392295D02*
X82426344Y-46935152D01*
X82083486Y-46592295D02*
X82540629Y-47049438D01*
X85598000Y-39674800D02*
X87020400Y-37998400D01*
X87020400Y-37998400D02*
X86868000Y-38862000D01*
X86207600Y-38252400D02*
X87020400Y-37998400D01*
D11*
X76370955Y-38024038D02*
X75228098Y-38024038D01*
@ -838,278 +1110,6 @@ X51894763Y-38690704D01*
X51894763Y-38690704D02*
X51704287Y-38785942D01*
D10*
X71345201Y-44393662D02*
X70869011Y-46393662D01*
X70869011Y-46393662D02*
X70488058Y-44965090D01*
X70488058Y-44965090D02*
X70107106Y-46393662D01*
X70107106Y-46393662D02*
X69630916Y-44393662D01*
X68869011Y-46393662D02*
X68869011Y-44393662D01*
X68011868Y-46393662D02*
X68011868Y-45346043D01*
X68011868Y-45346043D02*
X68107106Y-45155566D01*
X68107106Y-45155566D02*
X68297582Y-45060328D01*
X68297582Y-45060328D02*
X68583297Y-45060328D01*
X68583297Y-45060328D02*
X68773773Y-45155566D01*
X68773773Y-45155566D02*
X68869011Y-45250804D01*
X67059487Y-46393662D02*
X67059487Y-45060328D01*
X67059487Y-44393662D02*
X67154725Y-44488900D01*
X67154725Y-44488900D02*
X67059487Y-44584138D01*
X67059487Y-44584138D02*
X66964249Y-44488900D01*
X66964249Y-44488900D02*
X67059487Y-44393662D01*
X67059487Y-44393662D02*
X67059487Y-44584138D01*
X66392820Y-45060328D02*
X65630916Y-45060328D01*
X66107106Y-44393662D02*
X66107106Y-46107947D01*
X66107106Y-46107947D02*
X66011868Y-46298424D01*
X66011868Y-46298424D02*
X65821392Y-46393662D01*
X65821392Y-46393662D02*
X65630916Y-46393662D01*
X64202344Y-46298424D02*
X64392820Y-46393662D01*
X64392820Y-46393662D02*
X64773773Y-46393662D01*
X64773773Y-46393662D02*
X64964249Y-46298424D01*
X64964249Y-46298424D02*
X65059487Y-46107947D01*
X65059487Y-46107947D02*
X65059487Y-45346043D01*
X65059487Y-45346043D02*
X64964249Y-45155566D01*
X64964249Y-45155566D02*
X64773773Y-45060328D01*
X64773773Y-45060328D02*
X64392820Y-45060328D01*
X64392820Y-45060328D02*
X64202344Y-45155566D01*
X64202344Y-45155566D02*
X64107106Y-45346043D01*
X64107106Y-45346043D02*
X64107106Y-45536519D01*
X64107106Y-45536519D02*
X65059487Y-45726995D01*
X70488058Y-48565931D02*
X70202344Y-48661169D01*
X70202344Y-48661169D02*
X70107106Y-48756407D01*
X70107106Y-48756407D02*
X70011868Y-48946883D01*
X70011868Y-48946883D02*
X70011868Y-49232597D01*
X70011868Y-49232597D02*
X70107106Y-49423073D01*
X70107106Y-49423073D02*
X70202344Y-49518312D01*
X70202344Y-49518312D02*
X70392820Y-49613550D01*
X70392820Y-49613550D02*
X71154725Y-49613550D01*
X71154725Y-49613550D02*
X71154725Y-47613550D01*
X71154725Y-47613550D02*
X70488058Y-47613550D01*
X70488058Y-47613550D02*
X70297582Y-47708788D01*
X70297582Y-47708788D02*
X70202344Y-47804026D01*
X70202344Y-47804026D02*
X70107106Y-47994502D01*
X70107106Y-47994502D02*
X70107106Y-48184978D01*
X70107106Y-48184978D02*
X70202344Y-48375454D01*
X70202344Y-48375454D02*
X70297582Y-48470692D01*
X70297582Y-48470692D02*
X70488058Y-48565931D01*
X70488058Y-48565931D02*
X71154725Y-48565931D01*
X69154725Y-49613550D02*
X69154725Y-48280216D01*
X69154725Y-48661169D02*
X69059487Y-48470692D01*
X69059487Y-48470692D02*
X68964249Y-48375454D01*
X68964249Y-48375454D02*
X68773773Y-48280216D01*
X68773773Y-48280216D02*
X68583296Y-48280216D01*
X67630916Y-49613550D02*
X67821392Y-49518312D01*
X67821392Y-49518312D02*
X67916630Y-49423073D01*
X67916630Y-49423073D02*
X68011868Y-49232597D01*
X68011868Y-49232597D02*
X68011868Y-48661169D01*
X68011868Y-48661169D02*
X67916630Y-48470692D01*
X67916630Y-48470692D02*
X67821392Y-48375454D01*
X67821392Y-48375454D02*
X67630916Y-48280216D01*
X67630916Y-48280216D02*
X67345201Y-48280216D01*
X67345201Y-48280216D02*
X67154725Y-48375454D01*
X67154725Y-48375454D02*
X67059487Y-48470692D01*
X67059487Y-48470692D02*
X66964249Y-48661169D01*
X66964249Y-48661169D02*
X66964249Y-49232597D01*
X66964249Y-49232597D02*
X67059487Y-49423073D01*
X67059487Y-49423073D02*
X67154725Y-49518312D01*
X67154725Y-49518312D02*
X67345201Y-49613550D01*
X67345201Y-49613550D02*
X67630916Y-49613550D01*
X66297582Y-48280216D02*
X65916630Y-49613550D01*
X65916630Y-49613550D02*
X65535677Y-48661169D01*
X65535677Y-48661169D02*
X65154725Y-49613550D01*
X65154725Y-49613550D02*
X64773773Y-48280216D01*
X64011868Y-48280216D02*
X64011868Y-49613550D01*
X64011868Y-48470692D02*
X63916630Y-48375454D01*
X63916630Y-48375454D02*
X63726154Y-48280216D01*
X63726154Y-48280216D02*
X63440439Y-48280216D01*
X63440439Y-48280216D02*
X63249963Y-48375454D01*
X63249963Y-48375454D02*
X63154725Y-48565931D01*
X63154725Y-48565931D02*
X63154725Y-49613550D01*
X70107106Y-50928676D02*
X70297582Y-50833438D01*
X70297582Y-50833438D02*
X70583296Y-50833438D01*
X70583296Y-50833438D02*
X70869011Y-50928676D01*
X70869011Y-50928676D02*
X71059487Y-51119152D01*
X71059487Y-51119152D02*
X71154725Y-51309628D01*
X71154725Y-51309628D02*
X71249963Y-51690580D01*
X71249963Y-51690580D02*
X71249963Y-51976295D01*
X71249963Y-51976295D02*
X71154725Y-52357247D01*
X71154725Y-52357247D02*
X71059487Y-52547723D01*
X71059487Y-52547723D02*
X70869011Y-52738200D01*
X70869011Y-52738200D02*
X70583296Y-52833438D01*
X70583296Y-52833438D02*
X70392820Y-52833438D01*
X70392820Y-52833438D02*
X70107106Y-52738200D01*
X70107106Y-52738200D02*
X70011868Y-52642961D01*
X70011868Y-52642961D02*
X70011868Y-51976295D01*
X70011868Y-51976295D02*
X70392820Y-51976295D01*
X69154725Y-52833438D02*
X69154725Y-51500104D01*
X69154725Y-51881057D02*
X69059487Y-51690580D01*
X69059487Y-51690580D02*
X68964249Y-51595342D01*
X68964249Y-51595342D02*
X68773773Y-51500104D01*
X68773773Y-51500104D02*
X68583296Y-51500104D01*
X67154725Y-52738200D02*
X67345201Y-52833438D01*
X67345201Y-52833438D02*
X67726154Y-52833438D01*
X67726154Y-52833438D02*
X67916630Y-52738200D01*
X67916630Y-52738200D02*
X68011868Y-52547723D01*
X68011868Y-52547723D02*
X68011868Y-51785819D01*
X68011868Y-51785819D02*
X67916630Y-51595342D01*
X67916630Y-51595342D02*
X67726154Y-51500104D01*
X67726154Y-51500104D02*
X67345201Y-51500104D01*
X67345201Y-51500104D02*
X67154725Y-51595342D01*
X67154725Y-51595342D02*
X67059487Y-51785819D01*
X67059487Y-51785819D02*
X67059487Y-51976295D01*
X67059487Y-51976295D02*
X68011868Y-52166771D01*
X65440439Y-52738200D02*
X65630915Y-52833438D01*
X65630915Y-52833438D02*
X66011868Y-52833438D01*
X66011868Y-52833438D02*
X66202344Y-52738200D01*
X66202344Y-52738200D02*
X66297582Y-52547723D01*
X66297582Y-52547723D02*
X66297582Y-51785819D01*
X66297582Y-51785819D02*
X66202344Y-51595342D01*
X66202344Y-51595342D02*
X66011868Y-51500104D01*
X66011868Y-51500104D02*
X65630915Y-51500104D01*
X65630915Y-51500104D02*
X65440439Y-51595342D01*
X65440439Y-51595342D02*
X65345201Y-51785819D01*
X65345201Y-51785819D02*
X65345201Y-51976295D01*
X65345201Y-51976295D02*
X66297582Y-52166771D01*
X64488058Y-51500104D02*
X64488058Y-52833438D01*
X64488058Y-51690580D02*
X64392820Y-51595342D01*
X64392820Y-51595342D02*
X64202344Y-51500104D01*
X64202344Y-51500104D02*
X63916629Y-51500104D01*
X63916629Y-51500104D02*
X63726153Y-51595342D01*
X63726153Y-51595342D02*
X63630915Y-51785819D01*
X63630915Y-51785819D02*
X63630915Y-52833438D01*
X91562500Y-44069025D02*
X91864370Y-44716388D01*
X91864370Y-44716388D02*

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -1,11 +1,11 @@
%TF.GenerationSoftware,KiCad,Pcbnew,8.0.6*%
%TF.CreationDate,2024-12-19T11:27:53+03:00*%
%TF.CreationDate,2024-12-26T12:17:48+03:00*%
%TF.ProjectId,Hall,48616c6c-2e6b-4696-9361-645f70636258,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Profile,NP*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-19 11:27:53*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-26 12:17:48*
%MOMM*%
%LPD*%
G01*

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
%TF.GenerationSoftware,KiCad,Pcbnew,8.0.6*%
%TF.CreationDate,2024-12-19T11:27:53+03:00*%
%TF.CreationDate,2024-12-26T12:17:48+03:00*%
%TF.ProjectId,Hall,48616c6c-2e6b-4696-9361-645f70636258,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Soldermask,Top*%
%TF.FilePolarity,Negative*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-19 11:27:53*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-26 12:17:48*
%MOMM*%
%LPD*%
G01*
@ -46,35 +46,31 @@ G04 Aperture macros list*
0 $3 Rotation angle, in degrees counterclockwise*
0 Add horizontal line*
21,1,$1,$2,0,0,$3*%
%AMFreePoly0*
4,1,6,1.000000,0.000000,0.500000,-0.750000,-0.500000,-0.750000,-0.500000,0.750000,0.500000,0.750000,1.000000,0.000000,1.000000,0.000000,$1*%
%AMFreePoly1*
4,1,6,0.500000,-0.750000,-0.650000,-0.750000,-0.150000,0.000000,-0.650000,0.750000,0.500000,0.750000,0.500000,-0.750000,0.500000,-0.750000,$1*%
G04 Aperture macros list end*
%ADD10C,3.200000*%
%ADD11FreePoly0,0.000000*%
%ADD12FreePoly1,0.000000*%
%ADD13RoundRect,0.150000X-0.150000X0.587500X-0.150000X-0.587500X0.150000X-0.587500X0.150000X0.587500X0*%
%ADD14R,1.700000X1.700000*%
%ADD15O,1.700000X1.700000*%
%ADD16RoundRect,0.250001X-0.799999X-0.799999X0.799999X-0.799999X0.799999X0.799999X-0.799999X0.799999X0*%
%ADD17RoundRect,0.237500X-0.300000X-0.237500X0.300000X-0.237500X0.300000X0.237500X-0.300000X0.237500X0*%
%ADD18RoundRect,0.162500X0.162500X-0.617500X0.162500X0.617500X-0.162500X0.617500X-0.162500X-0.617500X0*%
%ADD19RoundRect,0.237500X0.300000X0.237500X-0.300000X0.237500X-0.300000X-0.237500X0.300000X-0.237500X0*%
%ADD20RoundRect,0.112500X0.637500X-0.112500X0.637500X0.112500X-0.637500X0.112500X-0.637500X-0.112500X0*%
%ADD21RoundRect,0.237500X-0.237500X0.300000X-0.237500X-0.300000X0.237500X-0.300000X0.237500X0.300000X0*%
%ADD22RoundRect,0.237500X-0.250000X-0.237500X0.250000X-0.237500X0.250000X0.237500X-0.250000X0.237500X0*%
%ADD23RoundRect,0.250000X0.475000X-0.337500X0.475000X0.337500X-0.475000X0.337500X-0.475000X-0.337500X0*%
%ADD24RoundRect,0.375000X-0.625000X-0.375000X0.625000X-0.375000X0.625000X0.375000X-0.625000X0.375000X0*%
%ADD25RoundRect,0.500000X-0.500000X-1.400000X0.500000X-1.400000X0.500000X1.400000X-0.500000X1.400000X0*%
%ADD26RoundRect,0.250000X1.000000X0.650000X-1.000000X0.650000X-1.000000X-0.650000X1.000000X-0.650000X0*%
%ADD27RoundRect,0.237500X0.237500X-0.250000X0.237500X0.250000X-0.237500X0.250000X-0.237500X-0.250000X0*%
%ADD28RoundRect,0.250000X0.650000X-0.412500X0.650000X0.412500X-0.650000X0.412500X-0.650000X-0.412500X0*%
%ADD29C,0.650000*%
%ADD30R,0.600000X1.450000*%
%ADD31R,0.300000X1.450000*%
%ADD32O,1.000000X2.100000*%
%ADD33O,1.000000X1.600000*%
%ADD10RoundRect,0.237500X-0.237500X0.250000X-0.237500X-0.250000X0.237500X-0.250000X0.237500X0.250000X0*%
%ADD11RoundRect,0.237500X0.237500X-0.250000X0.237500X0.250000X-0.237500X0.250000X-0.237500X-0.250000X0*%
%ADD12RoundRect,0.250000X-0.250000X0.250000X-0.250000X-0.250000X0.250000X-0.250000X0.250000X0.250000X0*%
%ADD13C,0.650000*%
%ADD14R,0.600000X1.450000*%
%ADD15R,0.300000X1.450000*%
%ADD16O,1.000000X2.100000*%
%ADD17O,1.000000X1.600000*%
%ADD18C,3.200000*%
%ADD19RoundRect,0.150000X-0.150000X0.587500X-0.150000X-0.587500X0.150000X-0.587500X0.150000X0.587500X0*%
%ADD20R,1.700000X1.700000*%
%ADD21O,1.700000X1.700000*%
%ADD22RoundRect,0.250001X-0.799999X-0.799999X0.799999X-0.799999X0.799999X0.799999X-0.799999X0.799999X0*%
%ADD23RoundRect,0.237500X-0.300000X-0.237500X0.300000X-0.237500X0.300000X0.237500X-0.300000X0.237500X0*%
%ADD24RoundRect,0.162500X0.162500X-0.617500X0.162500X0.617500X-0.162500X0.617500X-0.162500X-0.617500X0*%
%ADD25RoundRect,0.237500X0.300000X0.237500X-0.300000X0.237500X-0.300000X-0.237500X0.300000X-0.237500X0*%
%ADD26RoundRect,0.112500X0.637500X-0.112500X0.637500X0.112500X-0.637500X0.112500X-0.637500X-0.112500X0*%
%ADD27RoundRect,0.237500X-0.237500X0.300000X-0.237500X-0.300000X0.237500X-0.300000X0.237500X0.300000X0*%
%ADD28RoundRect,0.237500X-0.250000X-0.237500X0.250000X-0.237500X0.250000X0.237500X-0.250000X0.237500X0*%
%ADD29RoundRect,0.250000X0.475000X-0.337500X0.475000X0.337500X-0.475000X0.337500X-0.475000X-0.337500X0*%
%ADD30RoundRect,0.375000X-0.625000X-0.375000X0.625000X-0.375000X0.625000X0.375000X-0.625000X0.375000X0*%
%ADD31RoundRect,0.500000X-0.500000X-1.400000X0.500000X-1.400000X0.500000X1.400000X-0.500000X1.400000X0*%
%ADD32RoundRect,0.250000X1.000000X0.650000X-1.000000X0.650000X-1.000000X-0.650000X1.000000X-0.650000X0*%
%ADD33RoundRect,0.250000X0.650000X-0.412500X0.650000X0.412500X-0.650000X0.412500X-0.650000X-0.412500X0*%
%ADD34R,2.000000X2.400000*%
%ADD35RoundRect,0.250000X0.400000X1.075000X-0.400000X1.075000X-0.400000X-1.075000X0.400000X-1.075000X0*%
%ADD36RoundRect,0.075000X-0.075000X0.662500X-0.075000X-0.662500X0.075000X-0.662500X0.075000X0.662500X0*%
@ -84,42 +80,85 @@ G04 Aperture macros list end*
%ADD40HorizOval,1.000000X0.000000X0.000000X0.000000X0.000000X0*%
G04 APERTURE END LIST*
D10*
%TO.C,R3*%
X66167000Y-44704000D03*
X66167000Y-46529000D03*
%TD*%
D11*
%TO.C,R2*%
X64262000Y-46505500D03*
X64262000Y-44680500D03*
%TD*%
D12*
%TO.C,D1*%
X64262000Y-40386000D03*
X64262000Y-42886000D03*
%TD*%
D13*
%TO.C,J6*%
X67110000Y-66695000D03*
X72890000Y-66695000D03*
D14*
X66750000Y-65250000D03*
X67550000Y-65250000D03*
D15*
X68750000Y-65250000D03*
X69750000Y-65250000D03*
X70250000Y-65250000D03*
X71250000Y-65250000D03*
D14*
X72450000Y-65250000D03*
X73250000Y-65250000D03*
X73250000Y-65250000D03*
X72450000Y-65250000D03*
D15*
X71750000Y-65250000D03*
X70750000Y-65250000D03*
X69250000Y-65250000D03*
X68250000Y-65250000D03*
D14*
X67550000Y-65250000D03*
X66750000Y-65250000D03*
D16*
X65680000Y-66165000D03*
D17*
X65680000Y-70345000D03*
D16*
X74320000Y-66165000D03*
D17*
X74320000Y-70345000D03*
%TD*%
D18*
%TO.C,H3*%
X60444919Y-66632809D03*
%TD*%
D11*
%TO.C,JP1*%
X60907000Y-42799000D03*
D12*
X62357000Y-42799000D03*
%TD*%
D13*
%TO.C,D1*%
D19*
%TO.C,D2*%
X78740000Y-58724800D03*
X76840000Y-58724800D03*
X77790000Y-60599800D03*
%TD*%
D14*
D20*
%TO.C,J3*%
X61500000Y-46500000D03*
D15*
D21*
X61500000Y-49040000D03*
X61500000Y-51580000D03*
%TD*%
D16*
D22*
%TO.C,J4*%
X77216000Y-68376800D03*
%TD*%
D17*
D23*
%TO.C,C7*%
X77523000Y-31623000D03*
X79248000Y-31623000D03*
%TD*%
D16*
D22*
%TO.C,J5*%
X65405000Y-28575000D03*
X65405000Y-28321000D03*
%TD*%
D18*
D24*
%TO.C,U3*%
X69220000Y-58453000D03*
X70170000Y-58453000D03*
@ -128,106 +167,72 @@ X71120000Y-55753000D03*
X70170000Y-55753000D03*
X69220000Y-55753000D03*
%TD*%
D19*
D25*
%TO.C,C8*%
X68323800Y-52425600D03*
X66598800Y-52425600D03*
%TD*%
D20*
D26*
%TO.C,Q1*%
X80019200Y-56377600D03*
X80019200Y-55077600D03*
X77359200Y-55727600D03*
%TD*%
D19*
D25*
%TO.C,C2*%
X68707000Y-37973000D03*
X66982000Y-37973000D03*
%TD*%
D21*
D27*
%TO.C,C5*%
X78587600Y-40439000D03*
X78587600Y-42164000D03*
%TD*%
D22*
%TO.C,R5*%
D28*
%TO.C,R6*%
X73407900Y-55727600D03*
X75232900Y-55727600D03*
%TD*%
D23*
D29*
%TO.C,C3*%
X64363600Y-51097000D03*
X64363600Y-49022000D03*
X64643000Y-57701000D03*
X64643000Y-55626000D03*
%TD*%
D16*
D22*
%TO.C,J2*%
X64363600Y-61823600D03*
X63627000Y-61468000D03*
%TD*%
D24*
D30*
%TO.C,U2*%
X68605000Y-29323000D03*
X68605000Y-31623000D03*
D25*
D31*
X74905000Y-31623000D03*
D24*
D30*
X68605000Y-33923000D03*
%TD*%
D26*
%TO.C,D2*%
D32*
%TO.C,D3*%
X61658000Y-57658000D03*
X57658000Y-57658000D03*
%TD*%
D27*
D11*
%TO.C,R1*%
X84277200Y-38557200D03*
X84277200Y-36732200D03*
%TD*%
D22*
%TO.C,R7*%
X85599900Y-61569600D03*
X87424900Y-61569600D03*
%TD*%
D28*
%TO.C,R8*%
X85599900Y-61341000D03*
X87424900Y-61341000D03*
%TD*%
D33*
%TO.C,C9*%
X81534000Y-34748000D03*
X81534000Y-31623000D03*
%TD*%
D29*
%TO.C,J6*%
X67110000Y-66695000D03*
X72890000Y-66695000D03*
D30*
X66750000Y-65250000D03*
X67550000Y-65250000D03*
D31*
X68750000Y-65250000D03*
X69750000Y-65250000D03*
X70250000Y-65250000D03*
X71250000Y-65250000D03*
D30*
X72450000Y-65250000D03*
X73250000Y-65250000D03*
X73250000Y-65250000D03*
X72450000Y-65250000D03*
D31*
X71750000Y-65250000D03*
X70750000Y-65250000D03*
X69250000Y-65250000D03*
X68250000Y-65250000D03*
D30*
X67550000Y-65250000D03*
X66750000Y-65250000D03*
D32*
X65680000Y-66165000D03*
D33*
X65680000Y-70345000D03*
D32*
X74320000Y-66165000D03*
D33*
X74320000Y-70345000D03*
%TD*%
D27*
%TO.C,R4*%
D11*
%TO.C,R5*%
X69392800Y-62280800D03*
X69392800Y-60455800D03*
%TD*%
@ -236,35 +241,35 @@ D34*
X74875000Y-37973000D03*
X71175000Y-37973000D03*
%TD*%
D19*
D25*
%TO.C,C6*%
X78687000Y-52425600D03*
X76962000Y-52425600D03*
%TD*%
D17*
D23*
%TO.C,C1*%
X77216000Y-37973000D03*
X78941000Y-37973000D03*
%TD*%
D10*
D18*
%TO.C,H1*%
X60445087Y-31467095D03*
%TD*%
%TO.C,H2*%
X89976175Y-49050000D03*
%TD*%
D27*
%TO.C,R3*%
D11*
%TO.C,R4*%
X71018400Y-62280800D03*
X71018400Y-60455800D03*
%TD*%
D22*
%TO.C,R8*%
D28*
%TO.C,R9*%
X81385400Y-63347600D03*
X83210400Y-63347600D03*
%TD*%
D35*
%TO.C,R6*%
%TO.C,R7*%
X79451200Y-63347600D03*
X76351200Y-63347600D03*
%TD*%
@ -322,13 +327,13 @@ X76654100Y-44630400D03*
X76654100Y-44130400D03*
X76654100Y-43630400D03*
%TD*%
D17*
D23*
%TO.C,C4*%
X67007400Y-40335200D03*
X68732400Y-40335200D03*
%TD*%
D27*
%TO.C,R9*%
D11*
%TO.C,R10*%
X74371200Y-61870600D03*
X74371200Y-60045600D03*
%TD*%

View File

@ -1,12 +1,12 @@
%TF.GenerationSoftware,KiCad,Pcbnew,8.0.6*%
%TF.CreationDate,2024-12-19T11:27:53+03:00*%
%TF.CreationDate,2024-12-26T12:17:47+03:00*%
%TF.ProjectId,Hall,48616c6c-2e6b-4696-9361-645f70636258,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Paste,Top*%
%TF.FilePolarity,Positive*%
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-19 11:27:53*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-26 12:17:47*
%MOMM*%
%LPD*%
G01*
@ -29,39 +29,79 @@ G04 Aperture macros list*
20,1,$1+$1,$6,$7,$8,$9,0*
20,1,$1+$1,$8,$9,$2,$3,0*%
G04 Aperture macros list end*
%ADD10RoundRect,0.150000X-0.150000X0.587500X-0.150000X-0.587500X0.150000X-0.587500X0.150000X0.587500X0*%
%ADD11RoundRect,0.237500X-0.300000X-0.237500X0.300000X-0.237500X0.300000X0.237500X-0.300000X0.237500X0*%
%ADD12RoundRect,0.162500X0.162500X-0.617500X0.162500X0.617500X-0.162500X0.617500X-0.162500X-0.617500X0*%
%ADD13RoundRect,0.237500X0.300000X0.237500X-0.300000X0.237500X-0.300000X-0.237500X0.300000X-0.237500X0*%
%ADD14RoundRect,0.112500X0.637500X-0.112500X0.637500X0.112500X-0.637500X0.112500X-0.637500X-0.112500X0*%
%ADD15RoundRect,0.237500X-0.237500X0.300000X-0.237500X-0.300000X0.237500X-0.300000X0.237500X0.300000X0*%
%ADD16RoundRect,0.237500X-0.250000X-0.237500X0.250000X-0.237500X0.250000X0.237500X-0.250000X0.237500X0*%
%ADD17RoundRect,0.250000X0.475000X-0.337500X0.475000X0.337500X-0.475000X0.337500X-0.475000X-0.337500X0*%
%ADD18RoundRect,0.375000X-0.625000X-0.375000X0.625000X-0.375000X0.625000X0.375000X-0.625000X0.375000X0*%
%ADD19RoundRect,0.500000X-0.500000X-1.400000X0.500000X-1.400000X0.500000X1.400000X-0.500000X1.400000X0*%
%ADD20RoundRect,0.250000X1.000000X0.650000X-1.000000X0.650000X-1.000000X-0.650000X1.000000X-0.650000X0*%
%ADD21RoundRect,0.237500X0.237500X-0.250000X0.237500X0.250000X-0.237500X0.250000X-0.237500X-0.250000X0*%
%ADD22RoundRect,0.250000X0.650000X-0.412500X0.650000X0.412500X-0.650000X0.412500X-0.650000X-0.412500X0*%
%ADD23R,0.600000X1.450000*%
%ADD24R,0.300000X1.450000*%
%ADD25R,2.000000X2.400000*%
%ADD26RoundRect,0.250000X0.400000X1.075000X-0.400000X1.075000X-0.400000X-1.075000X0.400000X-1.075000X0*%
%ADD27RoundRect,0.075000X-0.075000X0.662500X-0.075000X-0.662500X0.075000X-0.662500X0.075000X0.662500X0*%
%ADD28RoundRect,0.075000X-0.662500X0.075000X-0.662500X-0.075000X0.662500X-0.075000X0.662500X0.075000X0*%
%ADD29RoundRect,0.150000X-0.150000X0.825000X-0.150000X-0.825000X0.150000X-0.825000X0.150000X0.825000X0*%
%ADD10RoundRect,0.237500X-0.237500X0.250000X-0.237500X-0.250000X0.237500X-0.250000X0.237500X0.250000X0*%
%ADD11RoundRect,0.237500X0.237500X-0.250000X0.237500X0.250000X-0.237500X0.250000X-0.237500X-0.250000X0*%
%ADD12RoundRect,0.250000X-0.250000X0.250000X-0.250000X-0.250000X0.250000X-0.250000X0.250000X0.250000X0*%
%ADD13R,0.600000X1.450000*%
%ADD14R,0.300000X1.450000*%
%ADD15RoundRect,0.150000X-0.150000X0.587500X-0.150000X-0.587500X0.150000X-0.587500X0.150000X0.587500X0*%
%ADD16RoundRect,0.237500X-0.300000X-0.237500X0.300000X-0.237500X0.300000X0.237500X-0.300000X0.237500X0*%
%ADD17RoundRect,0.162500X0.162500X-0.617500X0.162500X0.617500X-0.162500X0.617500X-0.162500X-0.617500X0*%
%ADD18RoundRect,0.237500X0.300000X0.237500X-0.300000X0.237500X-0.300000X-0.237500X0.300000X-0.237500X0*%
%ADD19RoundRect,0.112500X0.637500X-0.112500X0.637500X0.112500X-0.637500X0.112500X-0.637500X-0.112500X0*%
%ADD20RoundRect,0.237500X-0.237500X0.300000X-0.237500X-0.300000X0.237500X-0.300000X0.237500X0.300000X0*%
%ADD21RoundRect,0.237500X-0.250000X-0.237500X0.250000X-0.237500X0.250000X0.237500X-0.250000X0.237500X0*%
%ADD22RoundRect,0.250000X0.475000X-0.337500X0.475000X0.337500X-0.475000X0.337500X-0.475000X-0.337500X0*%
%ADD23RoundRect,0.375000X-0.625000X-0.375000X0.625000X-0.375000X0.625000X0.375000X-0.625000X0.375000X0*%
%ADD24RoundRect,0.500000X-0.500000X-1.400000X0.500000X-1.400000X0.500000X1.400000X-0.500000X1.400000X0*%
%ADD25RoundRect,0.250000X1.000000X0.650000X-1.000000X0.650000X-1.000000X-0.650000X1.000000X-0.650000X0*%
%ADD26RoundRect,0.250000X0.650000X-0.412500X0.650000X0.412500X-0.650000X0.412500X-0.650000X-0.412500X0*%
%ADD27R,2.000000X2.400000*%
%ADD28RoundRect,0.250000X0.400000X1.075000X-0.400000X1.075000X-0.400000X-1.075000X0.400000X-1.075000X0*%
%ADD29RoundRect,0.075000X-0.075000X0.662500X-0.075000X-0.662500X0.075000X-0.662500X0.075000X0.662500X0*%
%ADD30RoundRect,0.075000X-0.662500X0.075000X-0.662500X-0.075000X0.662500X-0.075000X0.662500X0.075000X0*%
%ADD31RoundRect,0.150000X-0.150000X0.825000X-0.150000X-0.825000X0.150000X-0.825000X0.150000X0.825000X0*%
G04 APERTURE END LIST*
D10*
%TO.C,R3*%
X66167000Y-44704000D03*
X66167000Y-46529000D03*
%TD*%
D11*
%TO.C,R2*%
X64262000Y-46505500D03*
X64262000Y-44680500D03*
%TD*%
D12*
%TO.C,D1*%
X64262000Y-40386000D03*
X64262000Y-42886000D03*
%TD*%
D13*
%TO.C,J6*%
X66750000Y-65250000D03*
X67550000Y-65250000D03*
D14*
X68750000Y-65250000D03*
X69750000Y-65250000D03*
X70250000Y-65250000D03*
X71250000Y-65250000D03*
D13*
X72450000Y-65250000D03*
X73250000Y-65250000D03*
X73250000Y-65250000D03*
X72450000Y-65250000D03*
D14*
X71750000Y-65250000D03*
X70750000Y-65250000D03*
X69250000Y-65250000D03*
X68250000Y-65250000D03*
D13*
X67550000Y-65250000D03*
X66750000Y-65250000D03*
%TD*%
D15*
%TO.C,D2*%
X78740000Y-58724800D03*
X76840000Y-58724800D03*
X77790000Y-60599800D03*
%TD*%
D11*
D16*
%TO.C,C7*%
X77523000Y-31623000D03*
X79248000Y-31623000D03*
%TD*%
D12*
D17*
%TO.C,U3*%
X69220000Y-58453000D03*
X70170000Y-58453000D03*
@ -70,125 +110,102 @@ X71120000Y-55753000D03*
X70170000Y-55753000D03*
X69220000Y-55753000D03*
%TD*%
D13*
D18*
%TO.C,C8*%
X68323800Y-52425600D03*
X66598800Y-52425600D03*
%TD*%
D14*
D19*
%TO.C,Q1*%
X80019200Y-56377600D03*
X80019200Y-55077600D03*
X77359200Y-55727600D03*
%TD*%
D13*
D18*
%TO.C,C2*%
X68707000Y-37973000D03*
X66982000Y-37973000D03*
%TD*%
D15*
D20*
%TO.C,C5*%
X78587600Y-40439000D03*
X78587600Y-42164000D03*
%TD*%
D16*
%TO.C,R5*%
D21*
%TO.C,R6*%
X73407900Y-55727600D03*
X75232900Y-55727600D03*
%TD*%
D17*
D22*
%TO.C,C3*%
X64363600Y-51097000D03*
X64363600Y-49022000D03*
X64643000Y-57701000D03*
X64643000Y-55626000D03*
%TD*%
D18*
D23*
%TO.C,U2*%
X68605000Y-29323000D03*
X68605000Y-31623000D03*
D19*
D24*
X74905000Y-31623000D03*
D18*
D23*
X68605000Y-33923000D03*
%TD*%
D20*
%TO.C,D2*%
D25*
%TO.C,D3*%
X61658000Y-57658000D03*
X57658000Y-57658000D03*
%TD*%
D21*
D11*
%TO.C,R1*%
X84277200Y-38557200D03*
X84277200Y-36732200D03*
%TD*%
D16*
%TO.C,R7*%
X85599900Y-61569600D03*
X87424900Y-61569600D03*
D21*
%TO.C,R8*%
X85599900Y-61341000D03*
X87424900Y-61341000D03*
%TD*%
D22*
D26*
%TO.C,C9*%
X81534000Y-34748000D03*
X81534000Y-31623000D03*
%TD*%
D23*
%TO.C,J6*%
X66750000Y-65250000D03*
X67550000Y-65250000D03*
D24*
X68750000Y-65250000D03*
X69750000Y-65250000D03*
X70250000Y-65250000D03*
X71250000Y-65250000D03*
D23*
X72450000Y-65250000D03*
X73250000Y-65250000D03*
X73250000Y-65250000D03*
X72450000Y-65250000D03*
D24*
X71750000Y-65250000D03*
X70750000Y-65250000D03*
X69250000Y-65250000D03*
X68250000Y-65250000D03*
D23*
X67550000Y-65250000D03*
X66750000Y-65250000D03*
%TD*%
D21*
%TO.C,R4*%
D11*
%TO.C,R5*%
X69392800Y-62280800D03*
X69392800Y-60455800D03*
%TD*%
D25*
D27*
%TO.C,Y1*%
X74875000Y-37973000D03*
X71175000Y-37973000D03*
%TD*%
D13*
D18*
%TO.C,C6*%
X78687000Y-52425600D03*
X76962000Y-52425600D03*
%TD*%
D11*
D16*
%TO.C,C1*%
X77216000Y-37973000D03*
X78941000Y-37973000D03*
%TD*%
D21*
%TO.C,R3*%
D11*
%TO.C,R4*%
X71018400Y-62280800D03*
X71018400Y-60455800D03*
%TD*%
D16*
%TO.C,R8*%
D21*
%TO.C,R9*%
X81385400Y-63347600D03*
X83210400Y-63347600D03*
%TD*%
D26*
%TO.C,R6*%
D28*
%TO.C,R7*%
X79451200Y-63347600D03*
X76351200Y-63347600D03*
%TD*%
D27*
D29*
%TO.C,U1*%
X75241600Y-42217900D03*
X74741600Y-42217900D03*
@ -202,7 +219,7 @@ X71241600Y-42217900D03*
X70741600Y-42217900D03*
X70241600Y-42217900D03*
X69741600Y-42217900D03*
D28*
D30*
X68329100Y-43630400D03*
X68329100Y-44130400D03*
X68329100Y-44630400D03*
@ -215,7 +232,7 @@ X68329100Y-47630400D03*
X68329100Y-48130400D03*
X68329100Y-48630400D03*
X68329100Y-49130400D03*
D27*
D29*
X69741600Y-50542900D03*
X70241600Y-50542900D03*
X70741600Y-50542900D03*
@ -228,7 +245,7 @@ X73741600Y-50542900D03*
X74241600Y-50542900D03*
X74741600Y-50542900D03*
X75241600Y-50542900D03*
D28*
D30*
X76654100Y-49130400D03*
X76654100Y-48630400D03*
X76654100Y-48130400D03*
@ -242,17 +259,17 @@ X76654100Y-44630400D03*
X76654100Y-44130400D03*
X76654100Y-43630400D03*
%TD*%
D11*
D16*
%TO.C,C4*%
X67007400Y-40335200D03*
X68732400Y-40335200D03*
%TD*%
D21*
%TO.C,R9*%
D11*
%TO.C,R10*%
X74371200Y-61870600D03*
X74371200Y-60045600D03*
%TD*%
D29*
D31*
%TO.C,U4*%
X87426800Y-54079600D03*
X86156800Y-54079600D03*

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
Drill report for Hall.kicad_pcb
Created on 2024-12-19T11:27:46+0300
Created on 2024-12-26T12:17:42+0300
Copper Layer Stackup:
=============================================================
@ -10,15 +10,15 @@ Copper Layer Stackup:
Drill file 'Hall.drl' contains
plated through holes:
=============================================================
T1 0.400mm 0.0157" (1 hole)
T2 0.600mm 0.0236" (27 holes)
T1 0.400mm 0.0157" (2 holes)
T2 0.600mm 0.0236" (34 holes)
T3 0.600mm 0.0236" (4 holes) (with 4 slots)
T4 0.650mm 0.0256" (6 holes)
T5 0.800mm 0.0315" (3 holes)
T6 1.000mm 0.0394" (3 holes)
T7 1.100mm 0.0433" (3 holes)
Total plated holes count 47
Total plated holes count 55
Not plated through holes are merged with plated holes

View File

@ -1,12 +1,12 @@
%TF.GenerationSoftware,KiCad,Pcbnew,8.0.6*%
%TF.CreationDate,2024-12-19T11:27:47+03:00*%
%TF.CreationDate,2024-12-26T12:17:43+03:00*%
%TF.ProjectId,Hall,48616c6c-2e6b-4696-9361-645f70636258,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Drillmap*%
%TF.FilePolarity,Positive*%
%FSLAX45Y45*%
G04 Gerber Fmt 4.5, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-19 11:27:47*
G04 Created by KiCad (PCBNEW 8.0.6) date 2024-12-26 12:17:43*
%MOMM*%
%LPD*%
G01*
@ -51,10 +51,34 @@ X4998515Y-5496270D02*
X5744798Y-5496270D01*
D11*
D12*
X7117400Y-4501200D02*
X7157400Y-4541200D01*
X7157400Y-4501200D02*
X7117400Y-4541200D01*
X7203760Y-4374200D02*
X7243760Y-4414200D01*
X7243760Y-4374200D02*
X7203760Y-4414200D01*
X5643400Y-3721100D02*
G75*
G02*
X5583400Y-3721100I-30000J0D01*
G01*
X5583400Y-3721100D02*
G75*
G02*
X5643400Y-3721100I30000J0D01*
G01*
X5656100Y-6019800D02*
G75*
G02*
X5596100Y-6019800I-30000J0D01*
G01*
X5596100Y-6019800D02*
G75*
G02*
X5656100Y-6019800I30000J0D01*
G01*
X6197120Y-5516880D02*
G75*
G02*
@ -65,6 +89,16 @@ G75*
G02*
X6197120Y-5516880I30000J0D01*
G01*
X6481600Y-3187700D02*
G75*
G02*
X6421600Y-3187700I-30000J0D01*
G01*
X6421600Y-3187700D02*
G75*
G02*
X6481600Y-3187700I30000J0D01*
G01*
X6634000Y-6350000D02*
G75*
G02*
@ -95,15 +129,15 @@ G75*
G02*
X6689880Y-5562600I30000J0D01*
G01*
X6824500Y-6083300D02*
X7015000Y-2705100D02*
G75*
G02*
X6764500Y-6083300I-30000J0D01*
X6955000Y-2705100I-30000J0D01*
G01*
X6764500Y-6083300D02*
X6955000Y-2705100D02*
G75*
G02*
X6824500Y-6083300I30000J0D01*
X7015000Y-2705100I30000J0D01*
G01*
X7294400Y-6083300D02*
G75*
@ -115,6 +149,16 @@ G75*
G02*
X7294400Y-6083300I30000J0D01*
G01*
X7345200Y-5346700D02*
G75*
G02*
X7285200Y-5346700I-30000J0D01*
G01*
X7285200Y-5346700D02*
G75*
G02*
X7345200Y-5346700I30000J0D01*
G01*
X7370600Y-6350000D02*
G75*
G02*
@ -165,6 +209,16 @@ G75*
G02*
X7822720Y-6558280I30000J0D01*
G01*
X7853200Y-4724400D02*
G75*
G02*
X7793200Y-4724400I-30000J0D01*
G01*
X7793200Y-4724400D02*
G75*
G02*
X7853200Y-4724400I30000J0D01*
G01*
X7939560Y-4389120D02*
G75*
G02*
@ -185,16 +239,6 @@ G75*
G02*
X7939560Y-4505960I30000J0D01*
G01*
X8046240Y-4724400D02*
G75*
G02*
X7986240Y-4724400I-30000J0D01*
G01*
X7986240Y-4724400D02*
G75*
G02*
X8046240Y-4724400I30000J0D01*
G01*
X8097040Y-6090920D02*
G75*
G02*
@ -205,25 +249,25 @@ G75*
G02*
X8097040Y-6090920I30000J0D01*
G01*
X8188480Y-4826280D02*
X8170700Y-4826280D02*
G75*
G02*
X8128480Y-4826280I-30000J0D01*
X8110700Y-4826280I-30000J0D01*
G01*
X8128480Y-4826280D02*
X8110700Y-4826280D02*
G75*
G02*
X8188480Y-4826280I30000J0D01*
X8170700Y-4826280I30000J0D01*
G01*
X8188480Y-5194300D02*
X8170700Y-5194300D02*
G75*
G02*
X8128480Y-5194300I-30000J0D01*
X8110700Y-5194300I-30000J0D01*
G01*
X8128480Y-5194300D02*
X8110700Y-5194300D02*
G75*
G02*
X8188480Y-5194300I30000J0D01*
X8170700Y-5194300I30000J0D01*
G01*
X8198640Y-3870960D02*
G75*
@ -235,6 +279,16 @@ G75*
G02*
X8198640Y-3870960I30000J0D01*
G01*
X8206841Y-4713659D02*
G75*
G02*
X8146841Y-4713659I-30000J0D01*
G01*
X8146841Y-4713659D02*
G75*
G02*
X8206841Y-4713659I30000J0D01*
G01*
X8249440Y-6060440D02*
G75*
G02*
@ -265,6 +319,16 @@ G75*
G02*
X8274840Y-4084320I30000J0D01*
G01*
X8305320Y-4800600D02*
G75*
G02*
X8245320Y-4800600I-30000J0D01*
G01*
X8245320Y-4800600D02*
G75*
G02*
X8305320Y-4800600I30000J0D01*
G01*
X8391680Y-5191760D02*
G75*
G02*
@ -325,6 +389,16 @@ G75*
G02*
X8676160Y-3581400I30000J0D01*
G01*
X8831100Y-4356100D02*
G75*
G02*
X8771100Y-4356100I-30000J0D01*
G01*
X8771100Y-4356100D02*
G75*
G02*
X8831100Y-4356100I30000J0D01*
G01*
X6568000Y-6586500D02*
X6568000Y-6646500D01*
X6538000Y-6616500D02*
@ -485,22 +559,22 @@ G02*
X6200000Y-5158000I50000J0D01*
G01*
D13*
X6381360Y-6127360D02*
X6491360Y-6237360D01*
X6491360Y-6127360D02*
X6381360Y-6237360D01*
X6436360Y-6127360D02*
X6436360Y-6237360D01*
X6381360Y-6182360D02*
X6491360Y-6182360D01*
X6485500Y-2802500D02*
X6595500Y-2912500D01*
X6595500Y-2802500D02*
X6485500Y-2912500D01*
X6540500Y-2802500D02*
X6540500Y-2912500D01*
X6485500Y-2857500D02*
X6595500Y-2857500D01*
X6307700Y-6091800D02*
X6417700Y-6201800D01*
X6417700Y-6091800D02*
X6307700Y-6201800D01*
X6362700Y-6091800D02*
X6362700Y-6201800D01*
X6307700Y-6146800D02*
X6417700Y-6146800D01*
X6485500Y-2777100D02*
X6595500Y-2887100D01*
X6595500Y-2777100D02*
X6485500Y-2887100D01*
X6540500Y-2777100D02*
X6540500Y-2887100D01*
X6485500Y-2832100D02*
X6595500Y-2832100D01*
X7666600Y-6782680D02*
X7776600Y-6892680D01*
X7776600Y-6782680D02*
@ -1051,16 +1125,26 @@ X8315007Y-7815867D02*
X8334055Y-7787295D01*
X8334055Y-7787295D02*
X8343578Y-7777771D01*
X8524531Y-8006343D02*
X8410245Y-8006343D01*
X8467388Y-8006343D02*
X8467388Y-7806343D01*
X8467388Y-7806343D02*
X8448340Y-7834914D01*
X8448340Y-7834914D02*
X8429293Y-7853962D01*
X8429293Y-7853962D02*
X8410245Y-7863486D01*
X8410245Y-7825390D02*
X8419769Y-7815867D01*
X8419769Y-7815867D02*
X8438817Y-7806343D01*
X8438817Y-7806343D02*
X8486436Y-7806343D01*
X8486436Y-7806343D02*
X8505483Y-7815867D01*
X8505483Y-7815867D02*
X8515007Y-7825390D01*
X8515007Y-7825390D02*
X8524531Y-7844438D01*
X8524531Y-7844438D02*
X8524531Y-7863486D01*
X8524531Y-7863486D02*
X8515007Y-7892057D01*
X8515007Y-7892057D02*
X8400721Y-8006343D01*
X8400721Y-8006343D02*
X8524531Y-8006343D01*
X8762626Y-8006343D02*
X8762626Y-7806343D01*
X8848340Y-8006343D02*
@ -1137,28 +1221,58 @@ X9315007Y-7901581D02*
X9315007Y-7920629D01*
X9315007Y-7920629D02*
X9219769Y-7939676D01*
X9381674Y-8082533D02*
X9391198Y-8073009D01*
X9391198Y-8073009D02*
X9410245Y-8044438D01*
X9410245Y-8044438D02*
X9419769Y-8025390D01*
X9419769Y-8025390D02*
X9429293Y-7996819D01*
X9429293Y-7996819D02*
X9438817Y-7949200D01*
X9438817Y-7949200D02*
X9438817Y-7911105D01*
X9438817Y-7911105D02*
X9429293Y-7863486D01*
X9429293Y-7863486D02*
X9419769Y-7834914D01*
X9419769Y-7834914D02*
X9410245Y-7815867D01*
X9410245Y-7815867D02*
X9391198Y-7787295D01*
X9391198Y-7787295D02*
X9381674Y-7777771D01*
X9391198Y-7996819D02*
X9410245Y-8006343D01*
X9410245Y-8006343D02*
X9448340Y-8006343D01*
X9448340Y-8006343D02*
X9467388Y-7996819D01*
X9467388Y-7996819D02*
X9476912Y-7977771D01*
X9476912Y-7977771D02*
X9476912Y-7968248D01*
X9476912Y-7968248D02*
X9467388Y-7949200D01*
X9467388Y-7949200D02*
X9448340Y-7939676D01*
X9448340Y-7939676D02*
X9419769Y-7939676D01*
X9419769Y-7939676D02*
X9400721Y-7930152D01*
X9400721Y-7930152D02*
X9391198Y-7911105D01*
X9391198Y-7911105D02*
X9391198Y-7901581D01*
X9391198Y-7901581D02*
X9400721Y-7882533D01*
X9400721Y-7882533D02*
X9419769Y-7873009D01*
X9419769Y-7873009D02*
X9448340Y-7873009D01*
X9448340Y-7873009D02*
X9467388Y-7882533D01*
X9543579Y-8082533D02*
X9553102Y-8073009D01*
X9553102Y-8073009D02*
X9572150Y-8044438D01*
X9572150Y-8044438D02*
X9581674Y-8025390D01*
X9581674Y-8025390D02*
X9591198Y-7996819D01*
X9591198Y-7996819D02*
X9600721Y-7949200D01*
X9600721Y-7949200D02*
X9600721Y-7911105D01*
X9600721Y-7911105D02*
X9591198Y-7863486D01*
X9591198Y-7863486D02*
X9581674Y-7834914D01*
X9581674Y-7834914D02*
X9572150Y-7815867D01*
X9572150Y-7815867D02*
X9553102Y-7787295D01*
X9553102Y-7787295D02*
X9543579Y-7777771D01*
D12*
X4768516Y-8178859D02*
G75*
@ -1601,30 +1715,38 @@ X8315007Y-8079867D02*
X8334055Y-8051295D01*
X8334055Y-8051295D02*
X8343578Y-8041771D01*
X8410245Y-8089390D02*
X8419769Y-8079867D01*
X8419769Y-8079867D02*
X8438817Y-8070343D01*
X8438817Y-8070343D02*
X8486436Y-8070343D01*
X8486436Y-8070343D02*
X8505483Y-8079867D01*
X8505483Y-8079867D02*
X8515007Y-8089390D01*
X8515007Y-8089390D02*
X8524531Y-8108438D01*
X8524531Y-8108438D02*
X8524531Y-8127486D01*
X8524531Y-8127486D02*
X8515007Y-8156057D01*
X8515007Y-8156057D02*
X8400721Y-8270343D01*
X8400721Y-8270343D02*
X8524531Y-8270343D01*
X8591198Y-8070343D02*
X8724531Y-8070343D01*
X8724531Y-8070343D02*
X8638817Y-8270343D01*
X8400721Y-8070343D02*
X8524531Y-8070343D01*
X8524531Y-8070343D02*
X8457864Y-8146533D01*
X8457864Y-8146533D02*
X8486436Y-8146533D01*
X8486436Y-8146533D02*
X8505483Y-8156057D01*
X8505483Y-8156057D02*
X8515007Y-8165581D01*
X8515007Y-8165581D02*
X8524531Y-8184629D01*
X8524531Y-8184629D02*
X8524531Y-8232248D01*
X8524531Y-8232248D02*
X8515007Y-8251295D01*
X8515007Y-8251295D02*
X8505483Y-8260819D01*
X8505483Y-8260819D02*
X8486436Y-8270343D01*
X8486436Y-8270343D02*
X8429293Y-8270343D01*
X8429293Y-8270343D02*
X8410245Y-8260819D01*
X8410245Y-8260819D02*
X8400721Y-8251295D01*
X8695959Y-8137009D02*
X8695959Y-8270343D01*
X8648340Y-8060819D02*
X8600721Y-8203676D01*
X8600721Y-8203676D02*
X8724531Y-8203676D01*
X8953102Y-8270343D02*
X8953102Y-8070343D01*
X9038817Y-8270343D02*

View File

@ -5,7 +5,7 @@
"Application": "Pcbnew",
"Version": "8.0.6"
},
"CreationDate": "2024-12-19T11:27:53+03:00"
"CreationDate": "2024-12-26T12:17:48+03:00"
},
"GeneralSpecs": {
"ProjectId": {
@ -28,8 +28,8 @@
"PadToTrack": 0.1,
"TrackToTrack": 0.1,
"MinLineWidth": 0.2,
"TrackToRegion": 0.508,
"RegionToRegion": 0.508
"TrackToRegion": 0.25,
"RegionToRegion": 0.25
}
],
"FilesAttributes": [

View File

@ -1,7 +1,7 @@
M48
; DRILL file {KiCad 8.0.6} date 2024-12-19T11:27:49+0300
; DRILL file {KiCad 8.0.6} date 2024-12-26T12:17:44+0300
; FORMAT={-:-/ absolute / metric / decimal}
; #@! TF.CreationDate,2024-12-19T11:27:49+03:00
; #@! TF.CreationDate,2024-12-26T12:17:44+03:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,8.0.6
; #@! TF.FileFunction,MixedPlating,1,2
FMAT,2
@ -28,35 +28,43 @@ T9C3.200
G90
G05
T1
X71.374Y-45.212
X72.238Y-43.942
T2
X56.134Y-37.211
X56.261Y-60.198
X61.671Y-55.169
X64.516Y-31.877
X66.04Y-63.5
X66.599Y-53.696
X66.599Y-55.626
X67.945Y-60.833
X69.85Y-27.051
X72.644Y-60.833
X73.152Y-53.467
X73.406Y-63.5
X73.965Y-58.776
X75.59Y-53.492
X76.962Y-53.797
X77.927Y-65.583
X78.232Y-47.244
X79.096Y-43.891
X79.096Y-45.06
X80.162Y-47.244
X80.67Y-60.909
X81.585Y-48.263
X81.585Y-51.943
X81.407Y-48.263
X81.407Y-51.943
X81.686Y-38.71
X81.768Y-47.137
X82.194Y-60.604
X82.347Y-66.548
X82.448Y-40.843
X82.753Y-48.006
X83.617Y-51.918
X84.328Y-32.969
X84.887Y-52.5
X86.004Y-50.5
X86.36Y-40.843
X86.462Y-35.814
X88.011Y-43.561
T4
X87.827Y-37.373
X88.363Y-38.524
@ -73,8 +81,8 @@ X61.5Y-46.5
X61.5Y-49.04
X61.5Y-51.58
T7
X64.364Y-61.824
X65.405Y-28.575
X63.627Y-61.468
X65.405Y-28.321
X77.216Y-68.377
T8
X67.11Y-66.695

View File

@ -0,0 +1,64 @@
/*
* This file is part of the canonmanage project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#include "adc.h"
#include "can.h"
#include "flash.h"
#include "hardware.h"
#include "proto.h"
#include "usb.h"
#define USBBUFSZ 256
volatile uint32_t Tms = 0;
void sys_tick_handler(void){
++Tms;
}
static int isUSB = FALSE;
int main(void){
char buf[USBBUFSZ];
StartHSE();
SysTick_Config(72000);
flashstorage_init();
hw_setup();
adc_setup();
USBPU_OFF();
if(ISUSB()){
isUSB = TRUE;
USB_setup();
USBPU_ON();
}else CAN_setup();
//uint32_t t = 0;
while(1){
IWDG->KR = IWDG_REFRESH;
/*if(Tms - t > 999){
t = Tms;
}*/
if(isUSB){
int g = USB_receivestr(buf, USBBUFSZ);
if(g < 0) USB_sendstr("USB buffer overflow detected\n");
else if(g > 0) parse_cmd(buf);
}else{
CAN_proc();
}
}
}

View File

@ -0,0 +1,6 @@
# STM32F103C8 "Blue Pill"
set FLASH_SIZE 0x20000
source [find interface/stlink-v2-1.cfg]
source [find target/stm32f1x.cfg]

173
F1:F103/Hall_linear/proto.c Normal file
View File

@ -0,0 +1,173 @@
/*
* This file is part of the canonmanage project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#include <string.h>
#include "adc.h"
#include "canproto.h" // errors
#include "flash.h"
#include "hardware.h"
#include "proto.h"
#include "strfunc.h"
#include "usb.h"
#include "version.inc"
const char* helpmsg =
"https://github.com/eddyem/stm32samples/tree/master/F1-nolib/Hall_linear build#" BUILD_NUMBER " @ " BUILD_DATE "\n"
"a - get ADC value (raw*Mul/Div)\n"
"d - change Div\n"
"m - change Mul\n"
"r - get Raw ADC value\n"
"u - get ADC voltage (*100)\n"
"\t\tdebugging/conf commands:\n"
"D - dump current config\n"
"E - erase full flash storage\n"
"F - reinit flashstorage\n"
"I - set CAN ID (11 bit)\n"
"M - show MCU temperature (*10)\n"
"R - software reset\n"
"S - set CAN speed (9600-3000000 baud)\n"
"T - show Tms value\n"
"V - get Vdd (*100)\n"
"X - save current config to flash\n"
;
static const char* const errors_txt[ERR_AMOUNT] = {
[ERR_OK] = "OK"
,[ERR_BADPAR] = "badpar"
,[ERR_BADVAL] = "badval"
,[ERR_WRONGLEN] = "wronglen"
,[ERR_BADCMD] = "badcmd"
,[ERR_CANTRUN] = "cantrun"
};
static void errtext(errcodes e){
if(e != ERR_OK) USB_sendstr("error=");
USB_sendstr(errors_txt[e]);
newline();
}
void parse_cmd(const char *buf){
int ret = ERR_CANTRUN;
if(!buf || *buf == 0) return;
uint32_t U, nan = 0;
if(buf[1] == '\n' || !buf[1]){ // one symbol commands
switch(*buf){
case 'D': // dump current config
dump_userconf();
return;
break;
case 'E': // erase full flash storage
if(0 == erase_storage(-1)) ret = ERR_OK;
break;
case 'F': // reinit flashstorage
flashstorage_init();
ret = ERR_OK;
break;
case 'M':
USB_sendstr("MCUt=");
printu(getMCUtemp());
newline(); return;
break;
case 'R': // software reset
USB_sendstr("Soft reset\n");
NVIC_SystemReset();
break;
case 'T': // show Tms value
USB_sendstr("Tms=");
printu(Tms);
newline(); return;
break;
case 'V':
USB_sendstr("VDD=");
printu(getVdd());
newline(); return;
break;
case 'X': // save current config to flash
if(0 == store_userconf()) ret = ERR_OK;
break;
case 'a': // get ADC value (raw*Mul/Div)
U = getADCval(ADC_CH_0) * the_conf.Mul;
USB_sendstr("ADC="); printu(U/the_conf.Div);
newline(); return;
break;
case 'r': // get Raw ADC value
USB_sendstr("ADCraw=");
printu(getADCval(ADC_CH_0));
newline(); return;
break;
case 'u': // get ADC voltage
USB_sendstr("ADCv=");
printu(getADCvoltage(ADC_CH_0));
newline(); return;
break;
default:
USB_sendstr(helpmsg);
return;
}
goto ret;
}
char cmd = *buf++;
const char *nxt = getnum(buf, &U);
if(nxt == buf){
nan = 1;
ret = ERR_BADVAL;
}
switch(cmd){ // long messages
case 'I': // can ID
if(nan) break;
else if(U >= 0x800) ret = ERR_WRONGLEN;
else{
the_conf.canID = U;
ret = ERR_OK;
}
break;
case 'S': // can speed
if(nan) break;
if(U < CAN_MIN_SPEED || U > CAN_MAX_SPEED) ret = ERR_WRONGLEN;
else{
the_conf.canspeed = U;
ret = ERR_OK;
}
break;
case 'd': // Divisor
if(nan) break;
if(U < 1 ) ret = ERR_WRONGLEN;
else{
the_conf.Div = U;
ret = ERR_OK;
}
break;
case 'm': // Multiplier
if(nan) break;
if(U < 1 || U > 1<<20) ret = ERR_WRONGLEN;
else{
the_conf.Mul = U;
ret = ERR_OK;
}
break;
default:
USB_sendstr(helpmsg);
return;
}
ret:
errtext(ret);
}

View File

@ -0,0 +1,27 @@
/*
* This file is part of the canonmanage project.
* Copyright 2022 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#pragma once
#ifndef PROTO_H__
#define PROTO_H__
#include <stm32f1.h>
void parse_cmd(const char *buf);
#endif // PROTO_H__

View File

@ -0,0 +1,167 @@
/*
* Copyright 2023 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#include "ringbuffer.h"
static int datalen(ringbuffer *b){
if(b->tail >= b->head) return (b->tail - b->head);
else return (b->length - b->head + b->tail);
}
// stored data length
int RB_datalen(ringbuffer *b){
if(b->busy) return -1;
b->busy = 1;
int l = datalen(b);
b->busy = 0;
return l;
}
static int hasbyte(ringbuffer *b, uint8_t byte){
if(b->head == b->tail) return -1; // no data in buffer
int startidx = b->head;
if(b->head > b->tail){ //
for(int found = b->head; found < b->length; ++found)
if(b->data[found] == byte) return found;
startidx = 0;
}
for(int found = startidx; found < b->tail; ++found)
if(b->data[found] == byte) return found;
return -1;
}
/**
* @brief RB_hasbyte - check if buffer has given byte stored
* @param b - buffer
* @param byte - byte to find
* @return index if found, -1 if none or busy
*/
int RB_hasbyte(ringbuffer *b, uint8_t byte){
if(b->busy) return -1;
b->busy = 1;
int ret = hasbyte(b, byte);
b->busy = 0;
return ret;
}
// poor memcpy
static void mcpy(uint8_t *targ, const uint8_t *src, int l){
while(l--) *targ++ = *src++;
}
// increment head or tail
TRUE_INLINE void incr(ringbuffer *b, volatile int *what, int n){
*what += n;
if(*what >= b->length) *what -= b->length;
}
static int read(ringbuffer *b, uint8_t *s, int len){
int l = datalen(b);
if(!l) return 0;
if(l > len) l = len;
int _1st = b->length - b->head;
if(_1st > l) _1st = l;
if(_1st > len) _1st = len;
mcpy(s, b->data + b->head, _1st);
if(_1st < len && l > _1st){
mcpy(s+_1st, b->data, l - _1st);
incr(b, &b->head, l);
return l;
}
incr(b, &b->head, _1st);
return _1st;
}
/**
* @brief RB_read - read data from ringbuffer
* @param b - buffer
* @param s - array to write data
* @param len - max len of `s`
* @return bytes read or -1 if busy
*/
int RB_read(ringbuffer *b, uint8_t *s, int len){
if(b->busy) return -1;
b->busy = 1;
int r = read(b, s, len);
b->busy = 0;
return r;
}
static int readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len){
int idx = hasbyte(b, byte);
if(idx < 0) return 0;
int partlen = idx + 1 - b->head;
// now calculate length of new data portion
if(idx < b->head) partlen += b->length;
if(partlen > len) return -read(b, s, len);
return read(b, s, partlen);
}
/**
* @brief RB_readto fill array `s` with data until byte `byte` (with it)
* @param b - ringbuffer
* @param byte - check byte
* @param s - buffer to write data
* @param len - length of `s`
* @return amount of bytes written (negative, if len<data in buffer or buffer is busy)
*/
int RB_readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len){
if(b->busy) return -1;
b->busy = 1;
int n = readto(b, byte, s, len);
b->busy = 0;
return n;
}
static int write(ringbuffer *b, const uint8_t *str, int l){
int r = b->length - 1 - datalen(b); // rest length
if(l > r) l = r;
if(!l) return 0;
int _1st = b->length - b->tail;
if(_1st > l) _1st = l;
mcpy(b->data + b->tail, str, _1st);
if(_1st < l){ // add another piece from start
mcpy(b->data, str+_1st, l-_1st);
}
incr(b, &b->tail, l);
return l;
}
/**
* @brief RB_write - write some data to ringbuffer
* @param b - buffer
* @param str - data
* @param l - length
* @return amount of bytes written or -1 if busy
*/
int RB_write(ringbuffer *b, const uint8_t *str, int l){
if(b->busy) return -1;
b->busy = 1;
int w = write(b, str, l);
b->busy = 0;
return w;
}
// just delete all information in buffer `b`
int RB_clearbuf(ringbuffer *b){
if(b->busy) return -1;
b->busy = 1;
b->head = 0;
b->tail = 0;
b->busy = 0;
return 1;
}

View File

@ -0,0 +1,41 @@
/*
* Copyright 2023 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#pragma once
#if defined STM32F0
#include <stm32f0.h>
#elif defined STM32F1
#include <stm32f1.h>
#elif defined STM32F3
#include <stm32f3.h>
#endif
typedef struct{
uint8_t *data; // data buffer
const int length; // its length
int head; // head index
int tail; // tail index
volatile int busy; // == TRUE if buffer is busy now
} ringbuffer;
int RB_read(ringbuffer *b, uint8_t *s, int len);
int RB_readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len);
int RB_hasbyte(ringbuffer *b, uint8_t byte);
int RB_write(ringbuffer *b, const uint8_t *str, int l);
int RB_datalen(ringbuffer *b);
int RB_clearbuf(ringbuffer *b);

View File

@ -0,0 +1,266 @@
/*
* This file is part of the fx3u project.
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#include <stm32f1.h>
#include <string.h>
/**
* @brief hexdump - dump hex array by 16 bytes in string
* @param sendfun - function to send data
* @param arr - array to dump
* @param len - length of `arr`
*/
void hexdump(int (*sendfun)(const char *s), uint8_t *arr, uint16_t len){
char buf[52], *bptr = buf;
for(uint16_t l = 0; l < len; ++l, ++arr){
for(int16_t j = 1; j > -1; --j){
register uint8_t half = (*arr >> (4*j)) & 0x0f;
if(half < 10) *bptr++ = half + '0';
else *bptr++ = half - 10 + 'a';
}
if(l % 16 == 15){
*bptr++ = '\n';
*bptr = 0;
sendfun(buf);
bptr = buf;
}else *bptr++ = ' ';
}
if(bptr != buf){
*bptr++ = '\n';
*bptr = 0;
sendfun(buf);
}
}
/**
* @brief _2str - convert value into string buffer
* @param val - |value|
* @param minus - ==0 if value > 0
* @return buffer with number
*/
static char *_2str(uint32_t val, uint8_t minus){
static char strbuf[12];
char *bufptr = &strbuf[11];
*bufptr = 0;
if(!val){
*(--bufptr) = '0';
}else{
while(val){
uint32_t x = val / 10;
*(--bufptr) = (val - 10*x) + '0';
val = x;
}
}
if(minus) *(--bufptr) = '-';
return bufptr;
}
// return string with number `val`
char *u2str(uint32_t val){
return _2str(val, 0);
}
char *i2str(int32_t i){
uint8_t minus = 0;
uint32_t val;
if(i < 0){
minus = 1;
val = -i;
}else val = i;
return _2str(val, minus);
}
/**
* @brief uhex2str - print 32bit unsigned int as hex
* @param val - value
* @return string with number
*/
char *uhex2str(uint32_t val){
static char buf[12] = "0x";
int npos = 2;
uint8_t *ptr = (uint8_t*)&val + 3;
int8_t i, j, z=1;
for(i = 0; i < 4; ++i, --ptr){
if(*ptr == 0){ // omit leading zeros
if(i == 3) z = 0;
if(z) continue;
}
else z = 0;
for(j = 1; j > -1; --j){
uint8_t half = (*ptr >> (4*j)) & 0x0f;
if(half < 10) buf[npos++] = half + '0';
else buf[npos++] = half - 10 + 'a';
}
}
buf[npos] = 0;
return buf;
}
/**
* @brief omit_spaces - eliminate leading spaces and other trash in string
* @param buf - string
* @return - pointer to first character in `buf` > ' '
*/
const char *omit_spaces(const char *buf){
while(*buf){
if(*buf > ' ') break;
++buf;
}
return buf;
}
/**
* @brief getdec - read decimal number & return pointer to next non-number symbol
* @param buf - string
* @param N - number read
* @return Next non-number symbol. In case of overflow return `buf` and N==0xffffffff
*/
static const char *getdec(const char *buf, uint32_t *N){
char *start = (char*)buf;
uint32_t num = 0;
while(*buf){
char c = *buf;
if(c < '0' || c > '9'){
break;
}
if(num > 429496729 || (num == 429496729 && c > '5')){ // overflow
*N = 0xffffff;
return start;
}
num *= 10;
num += c - '0';
++buf;
}
*N = num;
return buf;
}
// read hexadecimal number (without 0x prefix!)
static const char *gethex(const char *buf, uint32_t *N){
const char *start = buf;
uint32_t num = 0;
while(*buf){
char c = *buf;
uint8_t M = 0;
if(c >= '0' && c <= '9'){
M = '0';
}else if(c >= 'A' && c <= 'F'){
M = 'A' - 10;
}else if(c >= 'a' && c <= 'f'){
M = 'a' - 10;
}
if(M){
if(num & 0xf0000000){ // overflow
*N = 0xffffff;
return start;
}
num <<= 4;
num += c - M;
}else{
break;
}
++buf;
}
*N = num;
return buf;
}
// read octal number (without 0 prefix!)
static const char *getoct(const char *buf, uint32_t *N){
const char *start = (char*)buf;
uint32_t num = 0;
while(*buf){
char c = *buf;
if(c < '0' || c > '7'){
break;
}
if(num & 0xe0000000){ // overflow
*N = 0xffffff;
return start;
}
num <<= 3;
num += c - '0';
++buf;
}
*N = num;
return buf;
}
// read binary number (without b prefix!)
static const char *getbin(const char *buf, uint32_t *N){
const char *start = (char*)buf;
uint32_t num = 0;
while(*buf){
char c = *buf;
if(c < '0' || c > '1'){
break;
}
if(num & 0x80000000){ // overflow
*N = 0xffffff;
return start;
}
num <<= 1;
if(c == '1') num |= 1;
++buf;
}
*N = num;
return buf;
}
/**
* @brief getnum - read uint32_t from string (dec, hex or bin: 127, 0x7f, 0b1111111)
* @param buf - buffer with number and so on
* @param N - the number read
* @return pointer to first non-number symbol in buf
* (if it is == buf, there's no number or if *N==0xffffffff there was overflow)
*/
const char *getnum(const char *txt, uint32_t *N){
const char *nxt = NULL;
const char *s = omit_spaces(txt);
if(*s == '0'){ // hex, oct or 0
if(s[1] == 'x' || s[1] == 'X'){ // hex
nxt = gethex(s+2, N);
if(nxt == s+2) nxt = (char*)txt;
}else if(s[1] > '0'-1 && s[1] < '8'){ // oct
nxt = getoct(s+1, N);
if(nxt == s+1) nxt = (char*)txt;
}else{ // 0
nxt = s+1;
*N = 0;
}
}else if(*s == 'b' || *s == 'B'){
nxt = getbin(s+1, N);
if(nxt == s+1) nxt = (char*)txt;
}else{
nxt = getdec(s, N);
if(nxt == s) nxt = (char*)txt;
}
return nxt;
}
// get signed integer
const char *getint(const char *txt, int32_t *I){
const char *s = omit_spaces(txt);
int32_t sign = 1;
uint32_t U;
if(*s == '-'){
sign = -1;
++s;
}
const char *nxt = getnum(s, &U);
if(nxt == s) return txt;
if(U & 0x80000000) return txt; // overfull
*I = sign * (int32_t)U;
return nxt;
}

View File

@ -0,0 +1,38 @@
/*
* This file is part of the fx3u project.
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#pragma once
#include <stdint.h>
#ifndef _U_
#define _U_ __attribute__((__unused__))
#endif
void hexdump(int (*sendfun)(const char *s), uint8_t *arr, uint16_t len);
char *u2str(uint32_t val);
char *i2str(int32_t i);
char *uhex2str(uint32_t val);
const char *getnum(const char *txt, uint32_t *N);
const char *omit_spaces(const char *buf);
const char *getint(const char *txt, int32_t *I);
#define EQ() do{USB_putbyte('=');}while(0)
#define printu(a) do{USB_sendstr(u2str(a));}while(0)
#define printi(a) do{USB_sendstr(i2str(a));}while(0)
#define printuhex(a) do{USB_sendstr(uhex2str(a));}while(0)

135
F1:F103/Hall_linear/usb.c Normal file
View File

@ -0,0 +1,135 @@
/*
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#include <string.h>
#include "hardware.h"
#include "usb.h"
#include "usb_lib.h"
static volatile uint8_t usbbuff[USB_TXBUFSZ]; // temporary buffer for sending data
// ring buffers for incoming and outgoing data
static uint8_t obuf[RBOUTSZ], ibuf[RBINSZ];
volatile ringbuffer rbout = {.data = obuf, .length = RBOUTSZ, .head = 0, .tail = 0};
volatile ringbuffer rbin = {.data = ibuf, .length = RBINSZ, .head = 0, .tail = 0};
// inbuf overflow when receiving
volatile uint8_t bufovrfl = 0;
// last send data size
static volatile int lastdsz = 0;
// called from transmit EP
void send_next(){
int buflen = RB_read((ringbuffer*)&rbout, (uint8_t*)usbbuff, USB_TXBUFSZ);
if(buflen == 0){
if(lastdsz == 64) EP_Write(3, NULL, 0); // send ZLP after 64 bits packet when nothing more to send
lastdsz = 0;
return;
}else if(buflen < 0){
lastdsz = 0;
// Uncomment next line if you want 4Mbit/s instead of 6Mbit/s
//EP_Write(3, NULL, 0); // send ZLP if buffer is in writting state now
return;
}
EP_Write(3, (uint8_t*)usbbuff, buflen);
lastdsz = buflen;
}
// blocking send full content of ring buffer
int USB_sendall(){
while(lastdsz > 0){
if(!usbON) return FALSE;
}
return TRUE;
}
// put `buf` into queue to send
int USB_send(const uint8_t *buf, int len){
if(!buf || !usbON || !len) return FALSE;
while(len){
int a = RB_write((ringbuffer*)&rbout, buf, len);
if(a > 0){
len -= a;
buf += a;
} else if (a < 0) continue; // do nothing if buffer is in reading state
if(lastdsz == 0) send_next(); // need to run manually - all data sent, so no IRQ on IN
}
return TRUE;
}
int USB_putbyte(uint8_t byte){
if(!usbON) return FALSE;
int l = 0;
while((l = RB_write((ringbuffer*)&rbout, &byte, 1)) != 1){
if(l < 0) continue;
}
if(lastdsz == 0) send_next(); // need to run manually - all data sent, so no IRQ on IN
return TRUE;
}
int USB_sendstr(const char *string){
if(!string || !usbON) return FALSE;
int len = 0;
const char *b = string;
while(*b++) ++len;
if(!len) return FALSE;
return USB_send((const uint8_t*)string, len);
}
/**
* @brief USB_receive - get binary data from receiving ring-buffer
* @param buf (i) - buffer for received data
* @param len - length of `buf`
* @return amount of received bytes (negative, if overfull happened)
*/
int USB_receive(uint8_t *buf, int len){
chkin();
if(bufovrfl){
while(1 != RB_clearbuf((ringbuffer*)&rbin));
bufovrfl = 0;
return -1;
}
int sz = RB_read((ringbuffer*)&rbin, buf, len);
if(sz < 0) return 0; // buffer in writting state
return sz;
}
/**
* @brief USB_receivestr - get string up to '\n' and replace '\n' with 0
* @param buf - receiving buffer
* @param len - its length
* @return strlen or negative value indicating overflow (if so, string won't be ends with 0 and buffer should be cleared)
*/
int USB_receivestr(char *buf, int len){
chkin();
if(bufovrfl){
while(1 != RB_clearbuf((ringbuffer*)&rbin));
bufovrfl = 0;
return -1;
}
int l = RB_readto((ringbuffer*)&rbin, '\n', (uint8_t*)buf, len);
if(l < 1){
if(rbin.length == RB_datalen((ringbuffer*)&rbin)){ // buffer is full but no '\n' found
while(1 != RB_clearbuf((ringbuffer*)&rbin));
return -1;
}
return 0;
}
if(l == 0) return 0;
buf[l-1] = 0; // replace '\n' with strend
return l;
}

48
F1:F103/Hall_linear/usb.h Normal file
View File

@ -0,0 +1,48 @@
/*
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#pragma once
#include "ringbuffer.h"
#include "usbhw.h"
// sizes of ringbuffers for outgoing and incoming data
#define RBOUTSZ (512)
#define RBINSZ (256)
#define newline() USB_putbyte('\n')
#define USND(s) do{USB_sendstr(s); USB_putbyte('\n');}while(0)
#define STR_HELPER(s) #s
#define STR(s) STR_HELPER(s)
#ifdef EBUG
#define DBG(str) do{USB_sendstr(__FILE__ " (L" STR(__LINE__) "): " str); newline();}while(0)
#else
#define DBG(str)
#endif
extern volatile ringbuffer rbout, rbin;
extern volatile uint8_t bufisempty, bufovrfl;
void send_next();
int USB_sendall();
int USB_send(const uint8_t *buf, int len);
int USB_putbyte(uint8_t byte);
int USB_sendstr(const char *string);
int USB_receive(uint8_t *buf, int len);
int USB_receivestr(char *buf, int len);

View File

@ -0,0 +1,555 @@
/*
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#include <stdint.h>
#include "usb.h"
#include "usb_lib.h"
#include "usbhw.h"
ep_t endpoints[STM32ENDPOINTS];
static uint16_t USB_Addr = 0;
static usb_LineCoding lineCoding = {115200, 0, 0, 8};
uint8_t ep0databuf[EP0DATABUF_SIZE], setupdatabuf[EP0DATABUF_SIZE];
config_pack_t *setup_packet = (config_pack_t*) setupdatabuf;
usb_LineCoding getLineCoding(){return lineCoding;}
volatile uint8_t usbON = 0; // device disconnected from terminal
// definition of parts common for USB_DeviceDescriptor & USB_DeviceQualifierDescriptor
#define bcdUSB_L 0x10
#define bcdUSB_H 0x01
#define bDeviceClass 0
#define bDeviceSubClass 0
#define bDeviceProtocol 0
#define bNumConfigurations 1
static const uint8_t USB_DeviceDescriptor[] = {
18, // bLength
0x01, // bDescriptorType - Device descriptor
bcdUSB_L, // bcdUSB_L - 1.10
bcdUSB_H, // bcdUSB_H
bDeviceClass, // bDeviceClass - USB_COMM
bDeviceSubClass, // bDeviceSubClass
bDeviceProtocol, // bDeviceProtocol
USB_EP0_BUFSZ, // bMaxPacketSize
0x7b, // idVendor_L PL2303: VID=0x067b, PID=0x2303
0x06, // idVendor_H
0x03, // idProduct_L
0x23, // idProduct_H
0x00, // bcdDevice_Ver_L
0x03, // bcdDevice_Ver_H
iMANUFACTURER_DESCR, // iManufacturer
iPRODUCT_DESCR, // iProduct
iSERIAL_DESCR, // iSerialNumber
bNumConfigurations // bNumConfigurations
};
static const uint8_t USB_DeviceQualifierDescriptor[] = {
10, //bLength
0x06, // bDescriptorType - Device qualifier
bcdUSB_L, // bcdUSB_L
bcdUSB_H, // bcdUSB_H
bDeviceClass, // bDeviceClass
bDeviceSubClass, // bDeviceSubClass
bDeviceProtocol, // bDeviceProtocol
USB_EP0_BUFSZ, // bMaxPacketSize0
bNumConfigurations, // bNumConfigurations
0x00 // Reserved
};
static const uint8_t USB_ConfigDescriptor[] = {
/*Configuration Descriptor*/
0x09, /* bLength: Configuration Descriptor size */
0x02, /* bDescriptorType: Configuration */
39, /* wTotalLength:no of returned bytes */
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0xa0, /* bmAttributes - Bus powered, Remote wakeup */
0x32, /* MaxPower 100 mA */
/*---------------------------------------------------------------------------*/
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType: Interface */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x03, /* bNumEndpoints: 3 endpoints used */
0xff, /* bInterfaceClass */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
iINTERFACE_DESCR, /* iInterface: */
///////////////////////////////////////////////////
/*Endpoint 1 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x81, /* bEndpointAddress IN1 */
0x03, /* bmAttributes: Interrupt */
0x0a, /* wMaxPacketSize LO: */
0x00, /* wMaxPacketSize HI: */
0x01, /* bInterval: */
/*Endpoint OUT2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x02, /* bEndpointAddress: OUT2 */
0x02, /* bmAttributes: Bulk */
(USB_RXBUFSZ & 0xff), /* wMaxPacketSize: 64 */
(USB_RXBUFSZ >> 8),
0x00, /* bInterval: ignore for Bulk transfer */
/*Endpoint IN3 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x83, /* bEndpointAddress IN3 */
0x02, /* bmAttributes: Bulk */
(USB_TXBUFSZ & 0xff), /* wMaxPacketSize: 64 */
(USB_TXBUFSZ >> 8),
0x00, /* bInterval: ignore for Bulk transfer */
};
_USB_LANG_ID_(LD, LANG_US);
_USB_STRING_(SD, u"0.0.1");
_USB_STRING_(MD, u"Prolific Technology Inc.");
_USB_STRING_(PD, u"USB-Serial Controller");
_USB_STRING_(ID, u"hall-linear");
static void const *StringDescriptor[iDESCR_AMOUNT] = {
[iLANGUAGE_DESCR] = &LD,
[iMANUFACTURER_DESCR] = &MD,
[iPRODUCT_DESCR] = &PD,
[iSERIAL_DESCR] = &SD,
[iINTERFACE_DESCR] = &ID
};
/*
* default handlers
*/
// SET_LINE_CODING
void WEAK linecoding_handler(usb_LineCoding __attribute__((unused)) *lc){
}
// SET_CONTROL_LINE_STATE
void WEAK clstate_handler(uint16_t __attribute__((unused)) val){
}
// SEND_BREAK
void WEAK break_handler(){
}
// handler of vendor requests
void WEAK vendor_handler(config_pack_t *packet){
uint16_t c;
if(packet->bmRequestType & 0x80){ // read
switch(packet->wValue){
case 0x8484:
c = 2;
break;
case 0x0080:
c = 1;
break;
case 0x8686:
c = 0xaa;
break;
default:
c = 0;
}
EP_WriteIRQ(0, (uint8_t*)&c, 1);
}else{ // write ZLP
c = 0;
EP_WriteIRQ(0, (uint8_t *)&c, 0);
}
}
static void wr0(const uint8_t *buf, uint16_t size){
if(setup_packet->wLength < size) size = setup_packet->wLength; // shortened request
if(size < endpoints[0].txbufsz){
EP_WriteIRQ(0, buf, size);
return;
}
while(size){
uint16_t l = size;
if(l > endpoints[0].txbufsz) l = endpoints[0].txbufsz;
EP_WriteIRQ(0, buf, l);
buf += l;
size -= l;
uint8_t needzlp = (l == endpoints[0].txbufsz) ? 1 : 0;
if(size || needzlp){ // send last data buffer
uint16_t status = KEEP_DTOG(USB->EPnR[0]);
// keep DTOGs, clear CTR_RX,TX, set TX VALID, leave stat_Rx
USB->EPnR[0] = (status & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX|USB_EPnR_STAT_RX))
^ USB_EPnR_STAT_TX;
uint32_t ctr = 1000000;
while(--ctr && (USB->ISTR & USB_ISTR_CTR) == 0){IWDG->KR = IWDG_REFRESH;};
if((USB->ISTR & USB_ISTR_CTR) == 0){
return;
}
if(needzlp) EP_WriteIRQ(0, (uint8_t*)0, 0);
}
}
}
static inline void get_descriptor(){
uint8_t descrtype = setup_packet->wValue >> 8,
descridx = setup_packet->wValue & 0xff;
switch(descrtype){
case DEVICE_DESCRIPTOR:
wr0(USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor));
break;
case CONFIGURATION_DESCRIPTOR:
wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor));
break;
case STRING_DESCRIPTOR:
if(descridx < iDESCR_AMOUNT) wr0((const uint8_t *)StringDescriptor[descridx], *((uint8_t*)StringDescriptor[descridx]));
else EP_WriteIRQ(0, (uint8_t*)0, 0);
break;
case DEVICE_QUALIFIER_DESCRIPTOR:
wr0(USB_DeviceQualifierDescriptor, USB_DeviceQualifierDescriptor[0]);
break;
default:
break;
}
}
static uint16_t configuration = 0; // reply for GET_CONFIGURATION (==1 if configured)
static inline void std_d2h_req(){
uint16_t status = 0; // bus powered
switch(setup_packet->bRequest){
case GET_DESCRIPTOR:
get_descriptor();
break;
case GET_STATUS:
EP_WriteIRQ(0, (uint8_t *)&status, 2); // send status: Bus Powered
break;
case GET_CONFIGURATION:
EP_WriteIRQ(0, (uint8_t*)&configuration, 1);
break;
default:
break;
}
}
// interrupt IN handler (never used?)
static void EP1_Handler(){
uint16_t epstatus = KEEP_DTOG(USB->EPnR[1]);
if(RX_FLAG(epstatus)) epstatus = (epstatus & ~USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_RX; // set valid RX
else epstatus = epstatus & ~(USB_EPnR_STAT_TX|USB_EPnR_STAT_RX);
// clear CTR
epstatus = (epstatus & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX));
USB->EPnR[1] = epstatus;
}
// data IN/OUT handlers
static void transmit_Handler(){ // EP3IN
uint16_t epstatus = KEEP_DTOG_STAT(USB->EPnR[3]);
// clear CTR keep DTOGs & STATs
USB->EPnR[3] = (epstatus & ~(USB_EPnR_CTR_TX)); // clear TX ctr
send_next();
}
static uint8_t volatile rcvbuf[USB_RXBUFSZ];
static uint8_t volatile rcvbuflen = 0;
void chkin(){
if(bufovrfl) return;
if(!rcvbuflen) return;
int w = RB_write((ringbuffer*)&rbin, (uint8_t*)rcvbuf, rcvbuflen);
if(w < 0) return;
if(w != rcvbuflen) bufovrfl = 1;
rcvbuflen = 0;
uint16_t status = KEEP_DTOG(USB->EPnR[2]); // don't change DTOG
USB->EPnR[2] = status ^ USB_EPnR_STAT_RX;
}
// receiver reads data from local buffer and only then ACK'ed
static void receive_Handler(){ // EP2OUT
uint16_t status = KEEP_DTOG_STAT(USB->EPnR[2]); // don't change DTOG and NACK
if(rcvbuflen){
bufovrfl = 1; // lost last data
rcvbuflen = 0;
}
rcvbuflen = EP_Read(2, (uint8_t*)rcvbuf);
USB->EPnR[2] = status & ~USB_EPnR_CTR_RX;
}
static inline void std_h2d_req(){
switch(setup_packet->bRequest){
case SET_ADDRESS:
// new address will be assigned later - after acknowlegement or request to host
USB_Addr = setup_packet->wValue;
break;
case SET_CONFIGURATION:
// Now device configured
configuration = setup_packet->wValue;
EP_Init(1, EP_TYPE_INTERRUPT, USB_EP1BUFSZ, 0, EP1_Handler); // IN1 - transmit
EP_Init(2, EP_TYPE_BULK, 0, USB_RXBUFSZ, receive_Handler); // OUT2 - receive data
EP_Init(3, EP_TYPE_BULK, USB_TXBUFSZ, 0, transmit_Handler); // IN3 - transmit data
break;
default:
break;
}
}
/*
bmRequestType: 76543210
7 direction: 0 - host->device, 1 - device->host
65 type: 0 - standard, 1 - class, 2 - vendor
4..0 getter: 0 - device, 1 - interface, 2 - endpoint, 3 - other
*/
/**
* Endpoint0 (control) handler
*/
void EP0_Handler(){
uint16_t epstatus = USB->EPnR[0]; // EP0R on input -> return this value after modifications
uint8_t reqtype = setup_packet->bmRequestType & 0x7f;
uint8_t dev2host = (setup_packet->bmRequestType & 0x80) ? 1 : 0;
int rxflag = RX_FLAG(epstatus);
if(rxflag && SETUP_FLAG(epstatus)){
switch(reqtype){
case STANDARD_DEVICE_REQUEST_TYPE: // standard device request
if(dev2host){
std_d2h_req();
}else{
std_h2d_req();
EP_WriteIRQ(0, (uint8_t *)0, 0);
}
break;
case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request
if(setup_packet->bRequest == CLEAR_FEATURE){
EP_WriteIRQ(0, (uint8_t *)0, 0);
}
break;
case VENDOR_REQUEST_TYPE:
vendor_handler(setup_packet);
break;
case CONTROL_REQUEST_TYPE:
switch(setup_packet->bRequest){
case GET_LINE_CODING:
EP_WriteIRQ(0, (uint8_t*)&lineCoding, sizeof(lineCoding));
break;
case SET_LINE_CODING: // omit this for next stage, when data will come
break;
case SET_CONTROL_LINE_STATE:
usbON = 1;
clstate_handler(setup_packet->wValue);
break;
case SEND_BREAK:
usbON = 0;
break_handler();
break;
default:
break;
}
if(setup_packet->bRequest != GET_LINE_CODING) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement
break;
default:
EP_WriteIRQ(0, (uint8_t *)0, 0);
}
}else if(rxflag){ // got data over EP0 or host acknowlegement
if(endpoints[0].rx_cnt){
if(setup_packet->bRequest == SET_LINE_CODING){
linecoding_handler((usb_LineCoding*)ep0databuf);
}
}
} else if(TX_FLAG(epstatus)){ // package transmitted
// now we can change address after enumeration
if ((USB->DADDR & USB_DADDR_ADD) != USB_Addr){
USB->DADDR = USB_DADDR_EF | USB_Addr;
usbON = 0;
}
}
epstatus = KEEP_DTOG(USB->EPnR[0]);
if(rxflag) epstatus ^= USB_EPnR_STAT_TX; // start ZLP/data transmission
else epstatus &= ~USB_EPnR_STAT_TX; // or leave unchanged
// keep DTOGs, clear CTR_RX,TX, set RX VALID
USB->EPnR[0] = (epstatus & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX)) ^ USB_EPnR_STAT_RX;
}
/**
* Write data to EP buffer (called from IRQ handler)
* @param number - EP number
* @param *buf - array with data
* @param size - its size
*/
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){
if(size > endpoints[number].txbufsz) size = endpoints[number].txbufsz;
uint16_t N2 = (size + 1) >> 1;
// the buffer is 16-bit, so we should copy data as it would be uint16_t
uint16_t *buf16 = (uint16_t *)buf;
#if defined USB1_16
// very bad: what if `size` is odd?
uint32_t *out = (uint32_t *)endpoints[number].tx_buf;
for(int i = 0; i < N2; ++i, ++out){
*out = buf16[i];
}
#elif defined USB2_16
// use memcpy instead?
for(int i = 0; i < N2; i++){
endpoints[number].tx_buf[i] = buf16[i];
}
#else
#error "Define USB1_16 or USB2_16"
#endif
USB_BTABLE->EP[number].USB_COUNT_TX = size;
}
/**
* Write data to EP buffer (called outside IRQ handler)
* @param number - EP number
* @param *buf - array with data
* @param size - its size
*/
void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size){
EP_WriteIRQ(number, buf, size);
uint16_t status = KEEP_DTOG(USB->EPnR[number]);
// keep DTOGs, clear CTR_TX & set TX VALID to start transmission
USB->EPnR[number] = (status & ~(USB_EPnR_CTR_TX)) ^ USB_EPnR_STAT_TX;
}
/*
* Copy data from EP buffer into user buffer area
* @param *buf - user array for data
* @return amount of data read
*/
int EP_Read(uint8_t number, uint8_t *buf){
int sz = endpoints[number].rx_cnt;
if(!sz) return 0;
endpoints[number].rx_cnt = 0;
#if defined USB1_16
int n = (sz + 1) >> 1;
uint32_t *in = (uint32_t*)endpoints[number].rx_buf;
uint16_t *out = (uint16_t*)buf;
for(int i = 0; i < n; ++i, ++in)
out[i] = *(uint16_t*)in;
#elif defined USB2_16
// use memcpy instead?
for(int i = 0; i < sz; ++i)
buf[i] = endpoints[number].rx_buf[i];
#else
#error "Define USB1_16 or USB2_16"
#endif
return sz;
}
static uint16_t lastaddr = LASTADDR_DEFAULT;
/**
* Endpoint initialisation
* @param number - EP num (0...7)
* @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT)
* @param txsz - transmission buffer size @ USB/CAN buffer
* @param rxsz - reception buffer size @ USB/CAN buffer
* @param uint16_t (*func)(ep_t *ep) - EP handler function
* @return 0 if all OK
*/
int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(ep_t ep)){
if(number >= STM32ENDPOINTS) return 4; // out of configured amount
if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large
if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE/ACCESSZ) return 2; // out of btable
USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA);
USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1;
if(rxsz & 1 || rxsz > USB_BTABLE_SIZE) return 3; // wrong rx buffer size
uint16_t countrx = 0;
if(rxsz < 64) countrx = rxsz / 2;
else{
if(rxsz & 0x1f) return 3; // should be multiple of 32
countrx = 31 + rxsz / 32;
}
USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr;
endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ);
endpoints[number].txbufsz = txsz;
lastaddr += txsz;
USB_BTABLE->EP[number].USB_COUNT_TX = 0;
USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr;
endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ);
lastaddr += rxsz;
USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10;
endpoints[number].func = func;
return 0;
}
// standard IRQ handler
void USB_IRQ(){
/* // CAN bus
if(CAN1->RF0R & CAN_RF0R_FOVR0){ // FIFO overrun
CAN1->RF0R = CAN_RF0R_FOVR0; // clear flag
}*/
// USB bus
if(USB->ISTR & USB_ISTR_RESET){
usbON = 0;
// Reinit registers
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM;
// Endpoint 0 - CONTROL
// ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes!
lastaddr = LASTADDR_DEFAULT;
// clear address, leave only enable bit
USB->DADDR = USB_DADDR_EF;
if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){
return;
}
USB->ISTR = ~USB_ISTR_RESET;
}
if(USB->ISTR & USB_ISTR_CTR){
// EP number
uint8_t n = USB->ISTR & USB_ISTR_EPID;
// copy status register
uint16_t epstatus = USB->EPnR[n];
// copy received bytes amount
endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter
// check direction
if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit)
if(n == 0){ // control endpoint
if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack
EP_Read(0, setupdatabuf);
// interrupt handler will be called later
}else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf
EP_Read(0, ep0databuf);
}
}
}
// call EP handler
if(endpoints[n].func) endpoints[n].func(endpoints[n]);
}
if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep
usbON = 0;
#ifndef STM32F0
USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE;
#else
USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LPMODE;
#endif
USB->ISTR = ~USB_ISTR_SUSP;
}
if(USB->ISTR & USB_ISTR_WKUP){ // wakeup
#ifndef STM32F0
USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE); // clear suspend flags
#else
USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LPMODE);
#endif
USB->ISTR = ~USB_ISTR_WKUP;
}
}
#if defined STM32F3
void usb_lp_isr() __attribute__ ((alias ("USB_IRQ")));
#elif defined STM32F1
void usb_lp_can_rx0_isr() __attribute__ ((alias ("USB_IRQ")));
#elif defined STM32F0
void usb_isr() __attribute__ ((alias ("USB_IRQ")));
#endif

View File

@ -0,0 +1,172 @@
/*
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#pragma once
#include <wchar.h>
#include "usbhw.h"
#define EP0DATABUF_SIZE (64)
#define LASTADDR_DEFAULT (STM32ENDPOINTS * 8)
// bmRequestType & 0x7f
#define STANDARD_DEVICE_REQUEST_TYPE 0
#define STANDARD_ENDPOINT_REQUEST_TYPE 2
#define VENDOR_REQUEST_TYPE 0x40
#define CONTROL_REQUEST_TYPE 0x21
// bRequest, standard; for bmRequestType == 0x80
#define GET_STATUS 0x00
#define GET_DESCRIPTOR 0x06
#define GET_CONFIGURATION 0x08
// for bmRequestType == 0
#define CLEAR_FEATURE 0x01
#define SET_FEATURE 0x03 // unused
#define SET_ADDRESS 0x05
#define SET_DESCRIPTOR 0x07 // unused
#define SET_CONFIGURATION 0x09
// for bmRequestType == 0x81, 1 or 0xB2
#define GET_INTERFACE 0x0A // unused
#define SET_INTERFACE 0x0B // unused
#define SYNC_FRAME 0x0C // unused
#define VENDOR_REQUEST 0x01 // unused
// Class-Specific Control Requests
#define SEND_ENCAPSULATED_COMMAND 0x00 // unused
#define GET_ENCAPSULATED_RESPONSE 0x01 // unused
#define SET_COMM_FEATURE 0x02 // unused
#define GET_COMM_FEATURE 0x03 // unused
#define CLEAR_COMM_FEATURE 0x04 // unused
#define SET_LINE_CODING 0x20
#define GET_LINE_CODING 0x21
#define SET_CONTROL_LINE_STATE 0x22
#define SEND_BREAK 0x23
// control line states
#define CONTROL_DTR 0x01
#define CONTROL_RTS 0x02
// string descriptors
enum{
iLANGUAGE_DESCR,
iMANUFACTURER_DESCR,
iPRODUCT_DESCR,
iSERIAL_DESCR,
iINTERFACE_DESCR,
iDESCR_AMOUNT
};
// Types of descriptors
#define DEVICE_DESCRIPTOR 0x01
#define CONFIGURATION_DESCRIPTOR 0x02
#define STRING_DESCRIPTOR 0x03
#define DEVICE_QUALIFIER_DESCRIPTOR 0x06
#define RX_FLAG(epstat) (epstat & USB_EPnR_CTR_RX)
#define TX_FLAG(epstat) (epstat & USB_EPnR_CTR_TX)
#define SETUP_FLAG(epstat) (epstat & USB_EPnR_SETUP)
// EPnR bits manipulation
#define KEEP_DTOG_STAT(EPnR) (EPnR & ~(USB_EPnR_STAT_RX|USB_EPnR_STAT_TX|USB_EPnR_DTOG_RX|USB_EPnR_DTOG_TX))
#define KEEP_DTOG(EPnR) (EPnR & ~(USB_EPnR_DTOG_RX|USB_EPnR_DTOG_TX))
// EP types
#define EP_TYPE_BULK 0x00
#define EP_TYPE_CONTROL 0x01
#define EP_TYPE_ISO 0x02
#define EP_TYPE_INTERRUPT 0x03
#define LANG_US (uint16_t)0x0409
#define _USB_STRING_(name, str) \
static const struct name \
{ \
uint8_t bLength; \
uint8_t bDescriptorType; \
uint16_t bString[(sizeof(str) - 2) / 2]; \
\
} \
name = {sizeof(name), 0x03, str}
#define _USB_LANG_ID_(name, lng_id) \
\
static const struct name \
{ \
uint8_t bLength; \
uint8_t bDescriptorType; \
uint16_t bString; \
\
} \
name = {0x04, 0x03, lng_id}
// EP0 configuration packet
typedef struct {
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} config_pack_t;
// endpoints state
typedef struct{
uint16_t *tx_buf; // transmission buffer address
uint16_t txbufsz; // transmission buffer size
uint8_t *rx_buf; // reception buffer address
void (*func)(); // endpoint action function
unsigned rx_cnt : 10; // received data counter
} ep_t;
typedef struct {
uint32_t dwDTERate;
uint8_t bCharFormat;
#define USB_CDC_1_STOP_BITS 0
#define USB_CDC_1_5_STOP_BITS 1
#define USB_CDC_2_STOP_BITS 2
uint8_t bParityType;
#define USB_CDC_NO_PARITY 0
#define USB_CDC_ODD_PARITY 1
#define USB_CDC_EVEN_PARITY 2
#define USB_CDC_MARK_PARITY 3
#define USB_CDC_SPACE_PARITY 4
uint8_t bDataBits;
} __attribute__ ((packed)) usb_LineCoding;
typedef struct {
uint8_t bmRequestType;
uint8_t bNotificationType;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} __attribute__ ((packed)) usb_cdc_notification;
extern ep_t endpoints[];
extern volatile uint8_t usbON;
extern config_pack_t *setup_packet;
extern uint8_t ep0databuf[], setupdatabuf[];
void EP0_Handler();
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size);
void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size);
int EP_Read(uint8_t number, uint8_t *buf);
usb_LineCoding getLineCoding();
void linecoding_handler(usb_LineCoding *lc);
void clstate_handler(uint16_t val);
void break_handler();
void vendor_handler(config_pack_t *packet);
void chkin();
int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)());

View File

@ -0,0 +1,63 @@
/*
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#include "usb.h"
#include "usb_lib.h"
// here we suppose that all PIN settings done in hw_setup earlier
void USB_setup(){
#if defined STM32F3
NVIC_DisableIRQ(USB_LP_IRQn);
// remap USB LP & Wakeup interrupts to 75 and 76 - works only on pure F303
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // enable tacting of SYSCFG
SYSCFG->CFGR1 |= SYSCFG_CFGR1_USB_IT_RMP;
#elif defined STM32F1
NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn);
#elif defined STM32F0
NVIC_DisableIRQ(USB_IRQn);
RCC->APB1ENR |= RCC_APB1ENR_CRSEN;
RCC->CFGR3 &= ~RCC_CFGR3_USBSW; // reset USB
RCC->CR2 |= RCC_CR2_HSI48ON; // turn ON HSI48
uint32_t tmout = 16000000;
while(!(RCC->CR2 & RCC_CR2_HSI48RDY)){if(--tmout == 0) break;}
FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
CRS->CFGR &= ~CRS_CFGR_SYNCSRC;
CRS->CFGR |= CRS_CFGR_SYNCSRC_1; // USB SOF selected as sync source
CRS->CR |= CRS_CR_AUTOTRIMEN; // enable auto trim
CRS->CR |= CRS_CR_CEN; // enable freq counter & block CRS->CFGR as read-only
RCC->CFGR |= RCC_CFGR_SW;
#endif
RCC->APB1ENR |= RCC_APB1ENR_USBEN;
//??
USB->CNTR = USB_CNTR_FRES; // Force USB Reset
for(uint32_t ctr = 0; ctr < 72000; ++ctr) nop(); // wait >1ms
USB->CNTR = 0;
USB->BTABLE = 0;
USB->DADDR = 0;
USB->ISTR = 0;
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts
#if defined STM32F3
NVIC_EnableIRQ(USB_LP_IRQn);
#elif defined STM32F1
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
#elif defined STM32F0
USB->BCDR |= USB_BCDR_DPPU;
NVIC_EnableIRQ(USB_IRQn);
#endif
}

159
F1:F103/Hall_linear/usbhw.h Normal file
View File

@ -0,0 +1,159 @@
/*
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@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/>.
*/
#pragma once
#if defined STM32F0
#include <stm32f0.h>
#elif defined STM32F1
#include <stm32f1.h>
// there's no this define in standard header
#define USB_BASE ((uint32_t)0x40005C00)
#elif defined STM32F3
#include <stm32f3.h>
#endif
// max endpoints number
#define STM32ENDPOINTS 8
/**
* Buffers size definition
**/
// F0 - USB2_16; F1 - USB1_16; F3 - 1/2 depending on series
#if !defined USB1_16 && !defined USB2_16
#if defined STM32F0
#define USB2_16
#elif defined STM32F1
#define USB1_16
#else
#error "Can't determine USB1_16 or USB2_16, define by hands"
#endif
#endif
// BTABLE_SIZE FOR STM32F3:
// In STM32F303/302xB/C, 512 bytes SRAM is not shared with CAN.
// In STM32F302x6/x8 and STM32F30xxD/E, 726 bytes dedicated SRAM and 256 bytes shared SRAM with CAN i.e.
// 1Kbytes dedicated SRAM in case CAN is disabled.
// remember, that USB_BTABLE_SIZE will be divided by ACCESSZ, so don't divide it twice for 32-bit addressing
#ifdef NOCAN
#if defined STM32F0
#define USB_BTABLE_SIZE 1024
#elif defined STM32F3
#define USB_BTABLE_SIZE 512
#warning "Please, check real buffer size due to docs"
#else
#error "define STM32F0 or STM32F3"
#endif
#else // !NOCAN: F0/F3 with CAN or F1 (can't simultaneously run CAN and USB)
#if defined STM32F0
#define USB_BTABLE_SIZE 768
#elif defined STM32F3
#define USB_BTABLE_SIZE 512
#warning "Please, check real buffer size due to docs"
#else // STM32F103: 1024 bytes but with 32-bit addressing
#define USB_BTABLE_SIZE 1024
#endif
#endif // NOCAN
// first 64 bytes of USB_BTABLE are registers!
//#define USB_EP0_BASEADDR 64
// for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303)
#define USB_EP0_BUFSZ 64
// USB transmit buffer size (64 for PL2303)
#define USB_TXBUFSZ 64
// USB receive buffer size (64 for PL2303)
#define USB_RXBUFSZ 64
// EP1 - interrupt - buffer size
#define USB_EP1BUFSZ 8
#define USB_BTABLE_BASE 0x40006000
#define USB ((USB_TypeDef *) USB_BASE)
#ifdef USB_BTABLE
#undef USB_BTABLE
#endif
#define USB_BTABLE ((USB_BtableDef *)(USB_BTABLE_BASE))
#define USB_ISTR_EPID 0x0000000F
#define USB_FNR_LSOF_0 0x00000800
#define USB_FNR_lSOF_1 0x00001000
#define USB_LPMCSR_BESL_0 0x00000010
#define USB_LPMCSR_BESL_1 0x00000020
#define USB_LPMCSR_BESL_2 0x00000040
#define USB_LPMCSR_BESL_3 0x00000080
#define USB_EPnR_CTR_RX 0x00008000
#define USB_EPnR_DTOG_RX 0x00004000
#define USB_EPnR_STAT_RX 0x00003000
#define USB_EPnR_STAT_RX_0 0x00001000
#define USB_EPnR_STAT_RX_1 0x00002000
#define USB_EPnR_SETUP 0x00000800
#define USB_EPnR_EP_TYPE 0x00000600
#define USB_EPnR_EP_TYPE_0 0x00000200
#define USB_EPnR_EP_TYPE_1 0x00000400
#define USB_EPnR_EP_KIND 0x00000100
#define USB_EPnR_CTR_TX 0x00000080
#define USB_EPnR_DTOG_TX 0x00000040
#define USB_EPnR_STAT_TX 0x00000030
#define USB_EPnR_STAT_TX_0 0x00000010
#define USB_EPnR_STAT_TX_1 0x00000020
#define USB_EPnR_EA 0x0000000F
#define USB_COUNTn_RX_BLSIZE 0x00008000
#define USB_COUNTn_NUM_BLOCK 0x00007C00
#define USB_COUNTn_RX 0x0000003F
#define USB_TypeDef USB_TypeDef_custom
typedef struct {
__IO uint32_t EPnR[STM32ENDPOINTS];
__IO uint32_t RESERVED[STM32ENDPOINTS];
__IO uint32_t CNTR;
__IO uint32_t ISTR;
__IO uint32_t FNR;
__IO uint32_t DADDR;
__IO uint32_t BTABLE;
#ifdef STM32F0
__IO uint32_t LPMCSR;
__IO uint32_t BCDR;
#endif
} USB_TypeDef;
// F303 D/E have 2x16 access scheme
typedef struct{
#if defined USB2_16
__IO uint16_t USB_ADDR_TX;
__IO uint16_t USB_COUNT_TX;
__IO uint16_t USB_ADDR_RX;
__IO uint16_t USB_COUNT_RX;
#define ACCESSZ (1)
#define BUFTYPE uint8_t
#elif defined USB1_16
__IO uint32_t USB_ADDR_TX;
__IO uint32_t USB_COUNT_TX;
__IO uint32_t USB_ADDR_RX;
__IO uint32_t USB_COUNT_RX;
#define ACCESSZ (2)
#define BUFTYPE uint16_t
#else
#error "Define USB1_16 or USB2_16"
#endif
} USB_EPDATA_TypeDef;
typedef struct{
__IO USB_EPDATA_TypeDef EP[STM32ENDPOINTS];
} USB_BtableDef;
void USB_setup();

View File

@ -0,0 +1,2 @@
#define BUILD_NUMBER "6"
#define BUILD_DATE "2024-12-26"