WIP
This commit is contained in:
parent
d4cfddccaf
commit
646226a5ae
1 changed files with 105 additions and 27 deletions
132
src/main.c
132
src/main.c
|
|
@ -5,17 +5,23 @@
|
|||
|
||||
struct adc_state {
|
||||
enum {
|
||||
ADC_INIT_0 = 0,
|
||||
ADC_RESET = 0,
|
||||
ADC_RESET_RES,
|
||||
ADC_INIT_0,
|
||||
ADC_INIT_0_RES,
|
||||
ADC_INIT_1,
|
||||
ADC_INIT_1_RES,
|
||||
ADC_INIT_2,
|
||||
ADC_INIT_2_RES,
|
||||
ADC_INIT_3,
|
||||
ADC_INIT_4,
|
||||
ADC_INIT_3_RES,
|
||||
ADC_EMPTY_FIFO,
|
||||
ADC_RUNNING = 0x42,
|
||||
} state;
|
||||
size_t response_bytes;
|
||||
uint8_t txbuf[12];
|
||||
uint8_t rxbuf[12];
|
||||
uint16_t dma_ccr3;
|
||||
uint32_t dma_ccr3;
|
||||
int data[2];
|
||||
} st_adc;
|
||||
|
||||
|
|
@ -112,60 +118,113 @@ void adc_sm(bool reset);
|
|||
void adc_init(void);
|
||||
static void adc_prepare_read_samples(void);
|
||||
static void adc_schedule_read_reg(int addr);
|
||||
static void adc_schedule_reset(void);
|
||||
static void adc_schedule_null(void);
|
||||
static void adc_schedule_write_reg(int addr, int value);
|
||||
static void adc_setup_dma(size_t tx_bytes, size_t response_bytes);
|
||||
|
||||
|
||||
void adc_sm(bool reset) {
|
||||
GPIOA->BSRR = (1<<4);
|
||||
if (reset) {
|
||||
st_adc.state = ADC_INIT_0;
|
||||
adc_schedule_read_reg(ADC_REG_ID);
|
||||
TIM2->SMCR = TIM_SMCR_ETP | (7<<TIM_SMCR_TS_Pos) | (0<<TIM_SMCR_SMS_Pos);
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
st_adc.state = ADC_RESET;
|
||||
adc_schedule_reset();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (st_adc.state) {
|
||||
case ADC_RESET:
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
adc_schedule_null();
|
||||
st_adc.state = ADC_RESET_RES;
|
||||
break;
|
||||
|
||||
case ADC_RESET_RES:
|
||||
if (st_adc.rxbuf[0] != 0xff || st_adc.rxbuf[1] != 0x22) {
|
||||
adc_sm(true);
|
||||
} else {
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
adc_schedule_read_reg(ADC_REG_ID);
|
||||
st_adc.state = ADC_INIT_0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ADC_INIT_0:
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
adc_schedule_null();
|
||||
st_adc.state = ADC_INIT_0_RES;
|
||||
break;
|
||||
|
||||
case ADC_INIT_0_RES:
|
||||
if (st_adc.rxbuf[0] != 0x22) {
|
||||
adc_sm(true);
|
||||
} else {
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
adc_schedule_write_reg(ADC_REG_CLOCK, ADC_CLOCK_CH1_EN | ADC_CLOCK_CH2_EN | ADC_CLOCK_OSR_8192 | ADC_CLOCK_PWR_HIRES);
|
||||
st_adc.state = ADC_INIT_1;
|
||||
}
|
||||
break;
|
||||
|
||||
case ADC_INIT_1:
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
adc_schedule_null();
|
||||
st_adc.state = ADC_INIT_1_RES;
|
||||
break;
|
||||
|
||||
case ADC_INIT_1_RES:
|
||||
if (adc_check_write_response(ADC_REG_CLOCK)) {
|
||||
//asm volatile ("bkpt");
|
||||
adc_sm(true);
|
||||
} else {
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
adc_schedule_write_reg(ADC_REG_GAIN, ADC_GAIN1_PGAGAIN1_64 | ADC_GAIN1_PGAGAIN0_64);
|
||||
st_adc.state = ADC_INIT_2;
|
||||
}
|
||||
break;
|
||||
|
||||
case ADC_INIT_2:
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
adc_schedule_null();
|
||||
st_adc.state = ADC_INIT_2_RES;
|
||||
break;
|
||||
|
||||
case ADC_INIT_2_RES:
|
||||
if (adc_check_write_response(ADC_REG_GAIN)) {
|
||||
//asm volatile ("bkpt");
|
||||
adc_sm(true);
|
||||
} else {
|
||||
adc_schedule_write_reg(ADC_REG_CH0_CFG, ADC_CHn_CFG_DCBLK_DIS);
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
adc_schedule_write_reg(ADC_REG_MODE, (1<<ADC_MODE_WLENGTH_Pos) | ADC_MODE_TIMEOUT);
|
||||
st_adc.state = ADC_INIT_3;
|
||||
}
|
||||
break;
|
||||
|
||||
case ADC_INIT_3:
|
||||
if (adc_check_write_response(ADC_REG_CH0_CFG)) {
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
adc_schedule_null();
|
||||
st_adc.state = ADC_INIT_3_RES;
|
||||
break;
|
||||
|
||||
case ADC_INIT_3_RES:
|
||||
if (adc_check_write_response(ADC_REG_MODE)) {
|
||||
//asm volatile ("bkpt");
|
||||
adc_sm(true);
|
||||
} else {
|
||||
adc_schedule_write_reg(ADC_REG_CH1_CFG, ADC_CHn_CFG_DCBLK_DIS);
|
||||
st_adc.state = ADC_INIT_4;
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
adc_schedule_null();
|
||||
st_adc.state = ADC_EMPTY_FIFO;
|
||||
}
|
||||
break;
|
||||
|
||||
case ADC_INIT_4:
|
||||
if (adc_check_write_response(ADC_REG_CH1_CFG)) {
|
||||
adc_sm(true);
|
||||
case ADC_EMPTY_FIFO:
|
||||
if (GPIOA->IDR & (1<<0)) { /* DRDY */
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
adc_schedule_null();
|
||||
} else {
|
||||
adc_prepare_read_samples();
|
||||
st_adc.state = ADC_RUNNING;
|
||||
adc_prepare_read_samples();
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -173,6 +232,7 @@ void adc_sm(bool reset) {
|
|||
adc_prepare_read_samples();
|
||||
break;
|
||||
}
|
||||
GPIOA->BRR = (1<<4);
|
||||
}
|
||||
|
||||
void adc_init() {
|
||||
|
|
@ -182,7 +242,7 @@ void adc_init() {
|
|||
SPI1->CR1 |= SPI_CR1_SPE;
|
||||
|
||||
/* CH1 -> DRDY/TIM2-triggered start of conversion */
|
||||
DMA1_Channel1->CCR = (1<<DMA_CCR_MSIZE_Pos) | (1<<DMA_CCR_PSIZE_Pos) | DMA_CCR_TEIE | DMA_CCR_DIR | DMA_CCR_CIRC;
|
||||
DMA1_Channel1->CCR = (2<<DMA_CCR_MSIZE_Pos) | (2<<DMA_CCR_PSIZE_Pos) | DMA_CCR_TEIE | DMA_CCR_DIR | DMA_CCR_CIRC;
|
||||
DMA1_Channel1->CMAR = (uint32_t)&st_adc.dma_ccr3;
|
||||
DMA1_Channel1->CPAR = (uint32_t)&(DMA1_Channel3->CCR);
|
||||
DMA1_Channel1->CNDTR = 1;
|
||||
|
|
@ -197,11 +257,11 @@ void adc_init() {
|
|||
|
||||
TIM2->CR1 = TIM_CR1_OPM;
|
||||
TIM2->CR2 = TIM_CR2_CCDS | (5<<TIM_CR2_MMS_Pos); /* set trigger output to OC2REF */
|
||||
TIM2->SMCR = TIM_SMCR_ETP | (7<<TIM_SMCR_TS_Pos) | (6<<TIM_SMCR_SMS_Pos);
|
||||
TIM2->SMCR = TIM_SMCR_ETP | (7<<TIM_SMCR_TS_Pos) | (0<<TIM_SMCR_SMS_Pos);
|
||||
TIM2->DIER = TIM_DIER_CC3DE;
|
||||
TIM2->CCMR1 = (0<<TIM_CCMR1_CC1S_Pos) | (7<<TIM_CCMR1_OC2M_Pos);
|
||||
TIM2->CCER = TIM_CCER_CC1E;
|
||||
TIM2->CCR2 = 1; /* ~CS pulse */
|
||||
TIM2->CCMR2 = (0<<TIM_CCMR2_CC3S_Pos) | (7<<TIM_CCMR2_OC3M_Pos);
|
||||
TIM2->CCER = TIM_CCER_CC3E;
|
||||
TIM2->CCR3 = 8; /* ~CS pulse */
|
||||
TIM2->ARR = 32; /* Time to TX DMA request */
|
||||
|
||||
st_adc.dma_ccr3 = DMA1_Channel3->CCR | DMA_CCR_EN;
|
||||
|
|
@ -241,7 +301,7 @@ bool adc_check_write_response(size_t addr) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (st_adc.rxbuf[1] != (addr<<7)) {
|
||||
if (st_adc.rxbuf[1] != ((addr<<7)&0xff)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -259,10 +319,11 @@ void adc_prepare_read_samples() {
|
|||
|
||||
DMA1_Channel2->CCR &= ~DMA_CCR_EN;
|
||||
DMA1_Channel3->CCR &= ~DMA_CCR_EN;
|
||||
DMA1_Channel2->CNDTR = 3*3; /* RX DMA */
|
||||
DMA1_Channel3->CNDTR = 3*3; /* TX DMA */
|
||||
DMA1_Channel2->CNDTR = 4*3; /* RX DMA */
|
||||
DMA1_Channel3->CNDTR = 4*3; /* TX DMA */
|
||||
DMA1_Channel1->CCR |= DMA_CCR_EN;
|
||||
DMA1_Channel2->CCR |= DMA_CCR_EN;
|
||||
TIM2->SMCR = TIM_SMCR_ETP | (7<<TIM_SMCR_TS_Pos) | (6<<TIM_SMCR_SMS_Pos);
|
||||
}
|
||||
|
||||
void adc_schedule_read_reg(int addr) {
|
||||
|
|
@ -272,6 +333,21 @@ void adc_schedule_read_reg(int addr) {
|
|||
adc_setup_dma(3, 3);
|
||||
}
|
||||
|
||||
void adc_schedule_reset() {
|
||||
st_adc.txbuf[0] = 0x00;
|
||||
st_adc.txbuf[1] = 0x11;
|
||||
st_adc.txbuf[2] = 0;
|
||||
adc_setup_dma(3, 3);
|
||||
}
|
||||
|
||||
void adc_schedule_null() {
|
||||
st_adc.txbuf[0] = 0;
|
||||
st_adc.txbuf[1] = 0;
|
||||
st_adc.txbuf[2] = 0;
|
||||
adc_setup_dma(3, 3);
|
||||
}
|
||||
|
||||
|
||||
void adc_schedule_write_reg(int addr, int value) {
|
||||
st_adc.txbuf[0] = 0x60 | (addr >> 1);
|
||||
st_adc.txbuf[1] = (addr << 7);
|
||||
|
|
@ -283,12 +359,12 @@ void adc_schedule_write_reg(int addr, int value) {
|
|||
}
|
||||
|
||||
void adc_setup_dma(size_t tx_bytes, size_t response_bytes) {
|
||||
for (size_t i=0; i<COUNT_OF(st_adc.txbuf); i++) {
|
||||
for (size_t i=tx_bytes; i<COUNT_OF(st_adc.txbuf); i++) {
|
||||
st_adc.txbuf[i] = 0;
|
||||
}
|
||||
|
||||
size_t rx_len = st_adc.response_bytes + 2*3;
|
||||
size_t tx_len = tx_bytes;
|
||||
size_t rx_len = st_adc.response_bytes + 2*3 + 3;
|
||||
size_t tx_len = tx_bytes + 3;
|
||||
size_t len_bytes = rx_len > tx_len ? rx_len : tx_len;
|
||||
st_adc.response_bytes = response_bytes;
|
||||
|
||||
|
|
@ -360,9 +436,10 @@ int main(void) {
|
|||
* 15 - BT5
|
||||
*/
|
||||
GPIOA->MODER &= (~(CLEAR(15))); /* Clear JTAG TDI pin mode */
|
||||
GPIOA->MODER |= IN(0) | OUT(1) | AF(2) | ANALOG(3) | IN(4) | AF(5) | AF(6) | AF(7) | AF(8) | AF(9) | AF(10) | IN(11)
|
||||
GPIOA->MODER |= AF(0) | OUT(1) | AF(2) | ANALOG(3) | OUT(4) | AF(5) | AF(6) | AF(7) | AF(8) | AF(9) | AF(10) | IN(11)
|
||||
| IN(12) | IN(13) | IN(14) | IN(15);
|
||||
GPIOA->AFR[0] = AFRL( 2, 2) | /* TIM2 CH3 to ADC CS */
|
||||
GPIOA->AFR[0] = AFRL( 0, 2) | /* TIM2 ETR */
|
||||
AFRL( 2, 2) | /* TIM2 CH3 to ADC CS */
|
||||
AFRL( 5, 0) | /* SPI1 SCK (to ADC) */
|
||||
AFRL( 6, 0) | /* SPI1 HIPO */
|
||||
AFRL( 7, 0); /* SPI1 HOPI */
|
||||
|
|
@ -380,7 +457,8 @@ int main(void) {
|
|||
(3<<GPIO_OSPEEDR_OSPEEDR10_Pos) |
|
||||
(3<<GPIO_OSPEEDR_OSPEEDR13_Pos) |
|
||||
(3<<GPIO_OSPEEDR_OSPEEDR14_Pos);
|
||||
|
||||
GPIOA->BSRR = (1<<1); /* ADC ~SYNC */
|
||||
|
||||
/* GPIOB:
|
||||
* 0 - BT2
|
||||
* 1 - BT1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue