Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "scr1_csr_encoding.h"
- #include "riscv_csr_encoding.h"
- #include "mik32_memory_map.h"
- #include "power_manager.h"
- #include "pad_config.h"
- #include "epic.h"
- #include "uart.h"
- /*
- * Пример работы UART с прерываниями, данные поступают в кольцевой буфер
- * откуда забираются и отправляются обратно (режим эхо).
- */
- #define __disable_irq() __asm volatile("csrc mstatus, 8" )
- #define __enable_irq() __asm volatile("csrs mstatus, 8" )
- void uart1_initialize(uint32_t baud);
- uint8_t uart1_test(void);
- uint16_t uart1_getc(void);
- void uart1_putc(uint16_t d);
- #define BUFFER_SIZE 64
- typedef struct {
- uint8_t ri, wi, ct; // Read index, Write index, Data counter
- uint16_t buff[BUFFER_SIZE]; // FIFO buffer
- }FIFO;
- volatile FIFO TxFifo_1, RxFifo_1;
- void __attribute__((section(".ram_text"))) trap_handler(void)
- {
- if (EPIC->RAW_STATUS & (1<<EPIC_UART_1_INDEX)) {
- if(UART_1->FLAGS & UART_FLAGS_RXNE_M)
- {
- uint16_t d = UART_1->RXDATA;
- uint8_t i = RxFifo_1.ct;
- if(i < BUFFER_SIZE) {
- RxFifo_1.ct = ++i;
- i = RxFifo_1.wi;
- RxFifo_1.buff[i++] = d;
- RxFifo_1.wi = i % BUFFER_SIZE;
- }
- }
- if(UART_1->FLAGS & UART_FLAGS_TC_M){
- uint8_t ii = TxFifo_1.ct;
- if(ii){
- TxFifo_1.ct = --ii;
- ii = TxFifo_1.ri;
- UART_1->TXDATA = TxFifo_1.buff[ii++];
- TxFifo_1.ri = ii % BUFFER_SIZE;
- }
- else {
- UART_1->CONTROL1 &= ~UART_CONTROL1_TCIE_M;
- }
- }
- }
- }
- int main()
- {
- PM->CLK_APB_M_SET |= PM_CLOCK_APB_M_EPIC_M;
- uart1_initialize(115200);
- set_csr(mstatus, MSTATUS_MIE);
- set_csr(mie, MIE_MEIE);
- while (1)
- {
- if(uart1_test()){
- uart1_putc(uart1_getc());
- }
- }
- }
- void uart1_initialize(uint32_t baud)
- {
- uint8_t ready;
- PM->CLK_APB_P_SET |= PM_CLOCK_APB_P_UART_1_M | PM_CLOCK_APB_P_GPIO_1_M ;
- UART_1->CONTROL1 = 0;
- UART_1->DIVIDER = 32000000/baud;
- UART_1->FLAGS = 0xFFFFFFFF;
- UART_1->CONTROL2 = 0;
- UART_1->CONTROL3 = 0;
- UART_1->CONTROL1 = UART_CONTROL1_TE_M | UART_CONTROL1_RE_M | UART_CONTROL1_M_8BIT_M | UART_CONTROL1_UE_M;
- do
- {
- uint32_t flags = UART_1->FLAGS;
- ready = 1;
- if(UART_1->CONTROL1 & UART_CONTROL1_RE_M)
- {
- ready = ready && ((flags & UART_FLAGS_REACK_M) != 0);
- }
- if(UART_1->CONTROL1 & UART_CONTROL1_TE_M)
- {
- ready = ready && ((flags & UART_FLAGS_TEACK_M) != 0);
- }
- }while (!ready);
- /*************************************************************************************************************************/
- UART_1->TXDATA = 'A'; // это нужно для взведения флагов TC и TXE, чтобы при разрешении прерывания оно сразу и сработало.
- // идея в том чтобы первый байт умер внутри, не дойдя до выводов, а флаги взвелись
- while(!(UART_1->FLAGS & UART_FLAGS_TC_M));
- PAD_CONFIG->PORT_1_CFG = (PAD_CONFIG->PORT_1_CFG & ~(PAD_CONFIG_PIN_M(8) | PAD_CONFIG_PIN_M(9))) \
- | PAD_CONFIG_PIN(8,0x01) | PAD_CONFIG_PIN(9,0x01);
- /*************************************************************************************************************************/
- TxFifo_1.ri = 0; TxFifo_1.wi = 0; TxFifo_1.ct = 0;
- RxFifo_1.ri = 0; RxFifo_1.wi = 0; RxFifo_1.ct = 0;
- EPIC->MASK_LEVEL_SET |= 1 << EPIC_UART_1_INDEX;
- UART_1->CONTROL1 |= UART_CONTROL1_RXNEIE_M;
- }
- uint8_t uart1_test (void)
- {
- return RxFifo_1.ct;
- }
- uint16_t uart1_getc (void)
- {
- uint16_t d;
- uint16_t i;
- while (!RxFifo_1.ct) ; // Wait while Rx FIFO empty
- i = RxFifo_1.ri; // Get a byte from Rx FIFO
- d = RxFifo_1.buff[i++];
- RxFifo_1.ri = i % BUFFER_SIZE;
- __disable_irq();
- RxFifo_1.ct--;
- __enable_irq();
- return d;
- }
- void uart1_putc (uint16_t d)
- {
- uint16_t i;
- while (TxFifo_1.ct >= BUFFER_SIZE); //* Wait while Tx FIFO is full
- __disable_irq();
- i = TxFifo_1.wi; //* Put a data into the Tx FIFO
- TxFifo_1.buff[i++] = d;
- TxFifo_1.wi = i % BUFFER_SIZE;
- TxFifo_1.ct++;
- if(!(UART_1->CONTROL1 & UART_CONTROL1_TCIE_M)) //If transmission sequense is not running, start the tx sequense
- {
- UART_1->CONTROL1 |= UART_CONTROL1_TCIE_M;
- }
- __enable_irq();
- }
Advertisement
Add Comment
Please, Sign In to add comment