Working (but still dev-mode; need some more different configurators)

This commit is contained in:
2025-04-02 18:26:02 +03:00
parent c449cb7108
commit faeac98318
18 changed files with 476 additions and 95 deletions

View File

@@ -17,9 +17,10 @@
*/
#include <stm32f1.h>
#include "spi.h"
#include <string.h> // memcpy
#include "flash.h"
#include "spi.h"
#include "usb_dev.h"
#ifdef EBUG
#include "strfunc.h"
@@ -31,7 +32,7 @@
spiStatus spi_status[AMOUNT_OF_SPI+1] = {0, SPI_NOTREADY, SPI_NOTREADY};
static volatile SPI_TypeDef* const SPIs[AMOUNT_OF_SPI+1] = {NULL, SPI1, SPI2};
static volatile DMA_Channel_TypeDef * const DMAs[AMOUNT_OF_SPI+1] = {NULL, DMA1_Channel2, DMA1_Channel4};
#define WAITX(x) do{volatile uint32_t wctr = 0; while((x) && (++wctr < 360000)) IWDG->KR = IWDG_REFRESH; if(wctr==360000){ DBG("timeout"); return 0;}}while(0)
#define WAITX(x) do{volatile uint32_t wctr = 0; while((x) && (++wctr < 3600)) IWDG->KR = IWDG_REFRESH; if(wctr==3600){ DBG("timeout"); return 0;}}while(0)
static uint8_t encoderbuf[AMOUNT_OF_SPI][ENCODER_BUFSZ] = {0};
static uint8_t freshdata[AMOUNT_OF_SPI] = {0};
@@ -46,13 +47,14 @@ void spi_setup(uint8_t idx){
SPI->CR2 = 0;
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
volatile DMA_Channel_TypeDef *DMA = DMAs[idx];
uint32_t clkflags = 0;
if(idx == 1){ // PA5/PA6; 72MHz
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
RCC->APB2RSTR = RCC_APB2RSTR_SPI1RST;
RCC->APB2RSTR = 0; // clear reset
GPIOA->CRL = (GPIOA->CRL & ~(GPIO_CRL_CNF5 | GPIO_CRL_CNF6))
| CRL(5, CNF_AFPP|MODE_FAST) | CRL(6, CNF_FLINPUT);
SPI->CR1 = SPI_CR1_BR_1 | SPI_CR1_BR_2; // Fpclk/128
clkflags = ((uint32_t)the_conf.flags.BR) << 3;
NVIC_EnableIRQ(DMA1_Channel2_IRQn); // enable Rx interrupt
}else if(idx == 2){ // PB13/PB14; 36MHz
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
@@ -60,11 +62,14 @@ void spi_setup(uint8_t idx){
RCC->APB1RSTR = 0;
GPIOB->CRH = (GPIOB->CRH & ~(GPIO_CRH_CNF13 | GPIO_CRH_CNF14))
| CRH(13, CNF_AFPP|MODE_FAST) | CRH(14, CNF_FLINPUT);
SPI->CR1 = SPI_CR1_BR_0 | SPI_CR1_BR_2; // Fpclk/64
clkflags = ((uint32_t)the_conf.flags.BR - 1) << 3; // freq/2
NVIC_EnableIRQ(DMA1_Channel4_IRQn);
}else return; // err
// Baudrate = 0b110 - fpclk/128
SPI->CR1 |= SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_RXONLY;
// CPOL=1 (CLK is 1 on idle); CPHA=0 (capture in first front)
if(the_conf.flags.CPHA) clkflags |= SPI_CR1_CPHA;
if(the_conf.flags.CPOL) clkflags |= SPI_CR1_CPOL;
SPI->CR1 |= SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_RXONLY | clkflags;
SPI->CR2 = SPI_CR2_RXDMAEN;
DMA->CPAR = (uint32_t)&(SPI->DR);
DMA->CCR = DMA_CCR_MINC | DMA_CCR_TCIE | DMA_CCR_TEIE; // mem inc, hw->mem, Rx complete and error interrupt
@@ -76,8 +81,8 @@ void spi_onoff(uint8_t idx, uint8_t on){
CHKIDX(idx);
volatile SPI_TypeDef *SPI = SPIs[idx];
if(on){
DBGs(u2str(idx));
DBG("turn on SPI");
//DBGs(u2str(idx));
//DBG("turn on SPI");
SPI->CR1 |= SPI_CR1_SPE;
spi_status[idx] = SPI_BUSY;
}else{
@@ -117,9 +122,9 @@ static int spi_waitbsy(uint8_t idx){
// just copy last read encoder value into `buf`
// @return TRUE if got fresh data
int spi_read_enc(uint8_t encno, uint8_t buf[8]){
int spi_read_enc(uint8_t encno, uint8_t buf[ENCODER_BUFSZ]){
if(encno > 1 || !freshdata[encno]) return FALSE;
DBGs(u2str(encno)); DBG("Read encoder data");
//DBGs(u2str(encno)); DBG("Read encoder data");
memcpy(buf, encoderbuf[encno], ENCODER_BUFSZ);
freshdata[encno] = 0; // clear fresh status
return TRUE;
@@ -130,16 +135,16 @@ int spi_read_enc(uint8_t encno, uint8_t buf[8]){
// here `encodernum` is 0 (SPI1) or 1 (SPI2), not 1/2 as SPI index!
int spi_start_enc(int encodernum){
int spiidx = encodernum + 1;
DBG("start enc");
//DBG("start enc");
if(spiidx < 1 || spiidx > AMOUNT_OF_SPI) return FALSE;
if(spi_status[spiidx] != SPI_READY) return FALSE;
if(!spi_waitbsy(spiidx)) return FALSE;
if(SPI1->CR1 & SPI_CR1_SPE) DBG("spi1 works!");
if(SPI2->CR1 & SPI_CR1_SPE) DBG("spi2 works!");
if(SPI1->CR1 & SPI_CR1_SPE){ DBG("spi1 works!");}
if(SPI2->CR1 & SPI_CR1_SPE){ DBG("spi2 works!");}
volatile DMA_Channel_TypeDef *DMA = DMAs[spiidx];
DMA->CMAR = (uint32_t) encoderbuf[encodernum];
DMA->CNDTR = ENCODER_BUFSZ;
DBG("turn on spi");
//DBG("turn on spi");
spi_onoff(spiidx, 1);
DMA->CCR |= DMA_CCR_EN;
return TRUE;
@@ -149,6 +154,7 @@ int spi_start_enc(int encodernum){
void dma1_channel2_isr(){
// turn off DMA
DMA1_Channel2->CCR &= ~DMA_CCR_EN;
SPI1->CR1 &= ~SPI_CR1_SPE;
if(DMA1->ISR & DMA_ISR_TEIF2){
DMA1->IFCR = DMA_IFCR_CTEIF2;
}
@@ -160,12 +166,13 @@ void dma1_channel2_isr(){
//encoderbuf[6] = (ctr >> 8 ) & 0xff;
//encoderbuf[7] = (ctr >> 0 ) & 0xff;
}
spi_onoff(1, 0);
spi_status[1] = SPI_READY;
}
void dma1_channel4_isr(){
// turn off DMA
DMA1_Channel4->CCR &= ~DMA_CCR_EN;
SPI2->CR1 &= ~SPI_CR1_SPE;
if(DMA1->ISR & DMA_ISR_TEIF4){
DMA1->IFCR = DMA_IFCR_CTEIF4;
}
@@ -173,6 +180,6 @@ void dma1_channel4_isr(){
DMA1->IFCR = DMA_IFCR_CTCIF4;
freshdata[1] = 1;
}
spi_onoff(2, 0);
spi_status[2] = SPI_READY;
}