diff --git a/F1-nolib/inc/Fx/common_macros.h b/F1-nolib/inc/Fx/common_macros.h index e1cfe16..9e01f3b 100644 --- a/F1-nolib/inc/Fx/common_macros.h +++ b/F1-nolib/inc/Fx/common_macros.h @@ -38,8 +38,8 @@ gpioport->BSRR = ((__port & gpios) << 16) | (~__port & gpios);}while(0) #define pin_set(gpioport, gpios) do{gpioport->BSRR = gpios;}while(0) -#define pin_clear(gpioport, gpios) do{gpioport->BSRR = (gpios << 16);}while(0) -#define pin_read(gpioport, gpios) (gpioport->IDR & gpios ? 1 : 0) +#define pin_clear(gpioport, gpios) do{gpioport->BSRR = ((gpios) << 16);}while(0) +#define pin_read(gpioport, gpios) (gpioport->IDR & (gpios) ? 1 : 0) #define pin_write(gpioport, gpios) do{gpioport->ODR = gpios;}while(0) diff --git a/F1-nolib/inc/Fx/stm32f10x.h b/F1-nolib/inc/Fx/stm32f10x.h index 7c9753d..af784ab 100644 --- a/F1-nolib/inc/Fx/stm32f10x.h +++ b/F1-nolib/inc/Fx/stm32f10x.h @@ -3434,6 +3434,30 @@ typedef struct #define DMA_IFCR_CHTIF7 ((uint32_t)0x04000000) /*!< Channel 7 Half Transfer clear */ #define DMA_IFCR_CTEIF7 ((uint32_t)0x08000000) /*!< Channel 7 Transfer Error clear */ +#define DMA_CCR_EN ((uint16_t)0x0001) /*!< Channel enable*/ +#define DMA_CCR_TCIE ((uint16_t)0x0002) /*!< Transfer complete interrupt enable */ +#define DMA_CCR_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */ +#define DMA_CCR_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */ +#define DMA_CCR_DIR ((uint16_t)0x0010) /*!< Data transfer direction */ +#define DMA_CCR_CIRC ((uint16_t)0x0020) /*!< Circular mode */ +#define DMA_CCR_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */ +#define DMA_CCR_MINC ((uint16_t)0x0080) /*!< Memory increment mode */ + +#define DMA_CCR_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */ +#define DMA_CCR_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */ +#define DMA_CCR_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */ + +#define DMA_CCR_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */ +#define DMA_CCR_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */ +#define DMA_CCR_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */ + +#define DMA_CCR_PL ((uint16_t)0x3000) /*!< PL[1:0] bits(Channel Priority level) */ +#define DMA_CCR_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */ +#define DMA_CCR_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */ + +#define DMA_CCR_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */ + + /******************* Bit definition for DMA_CCR1 register *******************/ #define DMA_CCR1_EN ((uint16_t)0x0001) /*!< Channel enable*/ #define DMA_CCR1_TCIE ((uint16_t)0x0002) /*!< Transfer complete interrupt enable */ diff --git a/F1-nolib/uart/README b/F1-nolib/uart/README index 35bb182..cd185fe 100644 --- a/F1-nolib/uart/README +++ b/F1-nolib/uart/README @@ -1,5 +1,4 @@ -Toggle LEDs (PB8/PB9) on STM32F103 development board depending on buttons PC0,PC1: -- no buttons pressed == 'SOS' in Morze @ LED D1 -- Button S2 pressed - D1 blinks with period of 5s -- Button S1 pressed - D2 blinks with period of 1s - +Toggle LED PB9 on STM32F103 development board once per second +Allow to turn on/off LED PB8 depending on user commands over USART (0/1) and check its state (s) +Show information in USART console about S2/S3 buttons pressed +USART: 115200 8n1 diff --git a/F1-nolib/uart/main.c b/F1-nolib/uart/main.c index 6132830..5314846 100644 --- a/F1-nolib/uart/main.c +++ b/F1-nolib/uart/main.c @@ -22,6 +22,9 @@ #include "stm32f1.h" #include "usart.h" +// debounce pause (ms - 1) +#define DEBOUNCE_PAUSE (9) + static volatile uint32_t Tms = 0; // milliseconds from last reset // Called when systick fires @@ -40,6 +43,47 @@ static void gpio_setup(void){ GPIOC->CRL = CRL(0, CNF_PUDINPUT|MODE_INPUT) | CRL(1, CNF_PUDINPUT|MODE_INPUT); } +typedef enum{ + BTN_PRESSED + ,BTN_RELEASED + ,BTN_DEBOUNCE + ,BTN_RELAX +} button_state; + +button_state check_state(uint8_t N){ + static uint32_t tlast[2] = {0,0}; + static button_state oldstate[2] = {BTN_RELEASED, BTN_RELEASED}; + button_state s = BTN_RELAX; + uint8_t b = pin_read(GPIOC, N+1); // == 1 if button released + if(b){ + switch(oldstate[N]){ + case BTN_PRESSED: // debounce pause for DEBOUNCE_PAUSE ms + s = oldstate[N] = BTN_DEBOUNCE; + tlast[N] = Tms; + break; + case BTN_DEBOUNCE: // check debounce pause + if(Tms - tlast[N] > DEBOUNCE_PAUSE){ + s = oldstate[N] = BTN_RELEASED; + } + break; + default: // BTN_RELEASED - do nothing -> return BTN_RELAX + ; + } + }else{ + switch(oldstate[N]){ + case BTN_RELEASED: + s = BTN_PRESSED; // button was just pressed + __attribute__((fallthrough)); // change oldstate too + case BTN_DEBOUNCE: // change old state to BTN_PRESSED again + oldstate[N] = BTN_PRESSED; // returned state still relax + break; + default: // BTN_PRESSED before - do nothing + ; + } + } + return s; +} + int main(){ int L; char *txt; @@ -98,6 +142,26 @@ int main(){ transmit_tbuf(); L = 0; } + for(int i = 0; i < 2; ++i){ + const char *st = NULL; + switch(check_state(i)){ + case BTN_PRESSED: + st = "pressed"; + break; + case BTN_RELEASED: + st = "released"; + break; + default: + ; // nothing + } + if(st){ + SEND("The button"); + usart_putchar('2' + i); + SEND(" was "); + SEND(st); + newline(); + } + } /* uint8_t diff --git a/F1-nolib/uart/uart.bin b/F1-nolib/uart/uart.bin index 1b5a8ce..52f5580 100755 Binary files a/F1-nolib/uart/uart.bin and b/F1-nolib/uart/uart.bin differ diff --git a/F1-nolib/uart/usart.c b/F1-nolib/uart/usart.c index 25f41ea..900d259 100644 --- a/F1-nolib/uart/usart.c +++ b/F1-nolib/uart/usart.c @@ -53,32 +53,15 @@ int usart_getline(char **line){ // transmit current tbuf and swap buffers void transmit_tbuf(){ uint32_t tmout = 16000000; - while(!txrdy){if(--tmout == 0) break;}; // wait for previos buffer transmission + while(!txrdy){if(--tmout == 0) return;}; // wait for previos buffer transmission register int l = odatalen[tbufno]; if(!l) return; -//txrdy = 0; + txrdy = 0; odatalen[tbufno] = 0; - char *buf = tbuf[tbufno]; - for(int i = 0; i < l; ++i){ - USART1->DR = *buf++; - tmout = 16000000; - while(!(USART1->SR & USART_SR_TXE)){if(--tmout == 0)break;}; - } - /* -#if USARTNUM == 2 DMA1_Channel4->CCR &= ~DMA_CCR_EN; DMA1_Channel4->CMAR = (uint32_t) tbuf[tbufno]; // mem DMA1_Channel4->CNDTR = l; - DMA1_Channel4->CCR |= DMA_CCR_EN; // start transmission -#elif USARTNUM == 1 - DMA1_Channel2->CCR &= ~DMA_CCR_EN; - DMA1_Channel2->CMAR = (uint32_t) tbuf[tbufno]; // mem - DMA1_Channel2->CNDTR = l; - DMA1_Channel2->CCR |= DMA_CCR_EN; -#else -#error "Not implemented" -#endif -*/ + DMA1_Channel4->CCR |= DMA_CCR_EN; tbufno = !tbufno; } @@ -113,16 +96,15 @@ void usart_setup(){ uint32_t tmout = 16000000; // PA9 - Tx, PA10 - Rx RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN | RCC_APB2ENR_AFIOEN; + RCC->AHBENR |= RCC_AHBENR_DMA1EN; GPIOA->CRH = CRH(9, CNF_AFPP|MODE_NORMAL) | CRH(10, CNF_FLINPUT|MODE_INPUT); -/* - // USART1 Tx DMA - Channel2 (default value in SYSCFG_CFGR1) - DMA1_Channel2->CPAR = (uint32_t) &USART1->TDR; // periph - DMA1_Channel2->CMAR = (uint32_t) tbuf; // mem - DMA1_Channel2->CCR |= DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_TCIE; // 8bit, mem++, mem->per, transcompl irq + + // USART1 Tx DMA - Channel4 (Rx - channel 5) + DMA1_Channel4->CPAR = (uint32_t) &USART1->DR; // periph + DMA1_Channel4->CCR |= DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_TCIE; // 8bit, mem++, mem->per, transcompl irq // Tx CNDTR set @ each transmission due to data size - NVIC_SetPriority(DMA1_Channel2_3_IRQn, 3); - NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);*/ - //USART1->CR3 = USART_CR3_DMAT; // enable DMA Tx + NVIC_SetPriority(DMA1_Channel4_IRQn, 3); + NVIC_EnableIRQ(DMA1_Channel4_IRQn); NVIC_SetPriority(USART1_IRQn, 0); // setup usart1 USART1->BRR = 72000000 / 115200; @@ -130,6 +112,7 @@ void usart_setup(){ while(!(USART1->SR & USART_SR_TC)){if(--tmout == 0) break;} // polling idle frame Transmission USART1->SR = 0; // clear flags USART1->CR1 |= USART_CR1_RXNEIE; // allow Rx IRQ + USART1->CR3 = USART_CR3_DMAT; // enable DMA Tx NVIC_EnableIRQ(USART1_IRQn); } @@ -220,6 +203,14 @@ void hexdump(uint8_t *arr, uint16_t len){ else if(l & 1) usart_putchar(' '); } } + +void dma1_channel4_isr(){ + if(DMA1->ISR & DMA_ISR_TCIF4){ // Tx + DMA1->IFCR = DMA_IFCR_CTCIF4; // clear TC flag + txrdy = 1; + } +} + /* #if USARTNUM == 2 void dma1_channel4_5_isr(){ diff --git a/F1-nolib/uart/usart.h b/F1-nolib/uart/usart.h index 3ade072..8ab243d 100644 --- a/F1-nolib/uart/usart.h +++ b/F1-nolib/uart/usart.h @@ -24,8 +24,8 @@ #define __USART_H__ // input and output buffers size -#define UARTBUFSZI (32) -#define UARTBUFSZO (512) +#define UARTBUFSZI (16) +#define UARTBUFSZO (32) // timeout between data bytes #ifndef TIMEOUT_MS #define TIMEOUT_MS (1500)