Seongbin Lim
/
sb_first_project
This is a very simple guide, reviewing the steps required to get Blinky working on an Mbed OS platform.
main.cpp@139:78c21d98cff6, 2020-05-30 (annotated)
- Committer:
- sb8718
- Date:
- Sat May 30 08:17:30 2020 +0000
- Revision:
- 139:78c21d98cff6
- Parent:
- 138:e829be898713
DMA templete
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sb8718 | 109:5274dd9bebe1 | 1 | #include "mbed.h" |
sb8718 | 139:78c21d98cff6 | 2 | #include <stdlib.h> |
sb8718 | 139:78c21d98cff6 | 3 | #include <string.h> |
sb8718 | 139:78c21d98cff6 | 4 | |
sb8718 | 139:78c21d98cff6 | 5 | |
sb8718 | 139:78c21d98cff6 | 6 | RawSerial pc(PA_2, PA_3, 115200); |
sb8718 | 128:29911670c7fd | 7 | |
sb8718 | 139:78c21d98cff6 | 8 | void USART2_init(void); |
sb8718 | 139:78c21d98cff6 | 9 | void DMA1_init(void); |
sb8718 | 139:78c21d98cff6 | 10 | void DMA1_Stream6_setup(unsigned int src, unsigned int dst, int len); |
sb8718 | 139:78c21d98cff6 | 11 | |
sb8718 | 139:78c21d98cff6 | 12 | int done = 1; |
sb8718 | 139:78c21d98cff6 | 13 | |
sb8718 | 139:78c21d98cff6 | 14 | void send_DMA1_STEAM6_CH4(char str[], int len) |
sb8718 | 137:81b5a1672c6a | 15 | { |
sb8718 | 139:78c21d98cff6 | 16 | |
sb8718 | 139:78c21d98cff6 | 17 | char message[80]; |
sb8718 | 139:78c21d98cff6 | 18 | int i; |
sb8718 | 139:78c21d98cff6 | 19 | |
sb8718 | 139:78c21d98cff6 | 20 | USART2_init(); |
sb8718 | 139:78c21d98cff6 | 21 | DMA1_init(); |
sb8718 | 135:03997cc206a4 | 22 | |
sb8718 | 139:78c21d98cff6 | 23 | /* prepare the message for transfer */ |
sb8718 | 139:78c21d98cff6 | 24 | for (i = 0; i < len; i++) |
sb8718 | 139:78c21d98cff6 | 25 | message[i] = str[i]; |
sb8718 | 139:78c21d98cff6 | 26 | |
sb8718 | 139:78c21d98cff6 | 27 | /* send the message out by USART2 using DMA */ |
sb8718 | 139:78c21d98cff6 | 28 | while (done == 0) {} /* wait until DMA data transfer is done */ |
sb8718 | 139:78c21d98cff6 | 29 | done = 0; /* clear done flag */ |
sb8718 | 139:78c21d98cff6 | 30 | DMA1_Stream6_setup((unsigned int)message, (unsigned int)&USART2->DR, len); |
sb8718 | 139:78c21d98cff6 | 31 | |
sb8718 | 137:81b5a1672c6a | 32 | } |
sb8718 | 130:d19783810c05 | 33 | |
sb8718 | 139:78c21d98cff6 | 34 | |
sb8718 | 139:78c21d98cff6 | 35 | int main (void) |
sb8718 | 139:78c21d98cff6 | 36 | { |
sb8718 | 139:78c21d98cff6 | 37 | while (1) { |
sb8718 | 139:78c21d98cff6 | 38 | int size = 0; |
sb8718 | 139:78c21d98cff6 | 39 | char* buf = (char*)malloc(sizeof(char)*8); |
sb8718 | 139:78c21d98cff6 | 40 | pc.printf("Enter Fibonacci number n: \r\n"); |
sb8718 | 139:78c21d98cff6 | 41 | while(true) { |
sb8718 | 139:78c21d98cff6 | 42 | if (pc.readable()) { |
sb8718 | 139:78c21d98cff6 | 43 | int ch = pc.getc(); |
sb8718 | 139:78c21d98cff6 | 44 | pc.putc(ch); |
sb8718 | 139:78c21d98cff6 | 45 | if (ch == 0x0D) { |
sb8718 | 139:78c21d98cff6 | 46 | while(!pc.writeable()); |
sb8718 | 139:78c21d98cff6 | 47 | pc.putc(0x0A); |
sb8718 | 139:78c21d98cff6 | 48 | break; |
sb8718 | 139:78c21d98cff6 | 49 | } |
sb8718 | 139:78c21d98cff6 | 50 | buf[size] = ch; |
sb8718 | 139:78c21d98cff6 | 51 | size++; |
sb8718 | 139:78c21d98cff6 | 52 | } |
sb8718 | 139:78c21d98cff6 | 53 | } |
sb8718 | 139:78c21d98cff6 | 54 | int val = atoi(buf); |
sb8718 | 139:78c21d98cff6 | 55 | |
sb8718 | 139:78c21d98cff6 | 56 | if(val < 0 || val > 40) { |
sb8718 | 139:78c21d98cff6 | 57 | pc.printf("ERROR: n(%d) must be satisfied with '0 <= n <= 40'\r\n",val); |
sb8718 | 139:78c21d98cff6 | 58 | continue; |
sb8718 | 139:78c21d98cff6 | 59 | } |
sb8718 | 139:78c21d98cff6 | 60 | |
sb8718 | 139:78c21d98cff6 | 61 | size = val; |
sb8718 | 139:78c21d98cff6 | 62 | int *arr = (int*)malloc(sizeof(int)*size); |
sb8718 | 139:78c21d98cff6 | 63 | arr[0] = 0; |
sb8718 | 139:78c21d98cff6 | 64 | arr[1] = 1; |
sb8718 | 139:78c21d98cff6 | 65 | |
sb8718 | 139:78c21d98cff6 | 66 | for(int i = 2; i < size; i++) { |
sb8718 | 137:81b5a1672c6a | 67 | |
sb8718 | 139:78c21d98cff6 | 68 | arr[i] = arr[i-1] + arr[i-2]; |
sb8718 | 139:78c21d98cff6 | 69 | } |
sb8718 | 139:78c21d98cff6 | 70 | free(buf); |
sb8718 | 139:78c21d98cff6 | 71 | |
sb8718 | 139:78c21d98cff6 | 72 | buf = (char*)malloc(sizeof(char)*256); |
sb8718 | 139:78c21d98cff6 | 73 | |
sb8718 | 139:78c21d98cff6 | 74 | for(int i = 0; i < size; i ++) { |
sb8718 | 139:78c21d98cff6 | 75 | |
sb8718 | 139:78c21d98cff6 | 76 | char temp[64]; |
sb8718 | 139:78c21d98cff6 | 77 | sprintf(temp, "%d ", arr[i]); |
sb8718 | 139:78c21d98cff6 | 78 | strcat(buf, temp); |
sb8718 | 139:78c21d98cff6 | 79 | |
sb8718 | 139:78c21d98cff6 | 80 | if(i%5 == 0) { |
sb8718 | 139:78c21d98cff6 | 81 | strcat(buf, "\r\n"); |
sb8718 | 139:78c21d98cff6 | 82 | } |
sb8718 | 139:78c21d98cff6 | 83 | } |
sb8718 | 139:78c21d98cff6 | 84 | strcat(buf, "\r\n"); |
sb8718 | 139:78c21d98cff6 | 85 | |
sb8718 | 139:78c21d98cff6 | 86 | pc.printf("buf\r\n"); |
sb8718 | 139:78c21d98cff6 | 87 | |
sb8718 | 139:78c21d98cff6 | 88 | pc.printf("%s\r\n",buf); |
sb8718 | 139:78c21d98cff6 | 89 | pc.printf("\\buf\r\n"); |
sb8718 | 139:78c21d98cff6 | 90 | |
sb8718 | 139:78c21d98cff6 | 91 | char sub[8]; |
sb8718 | 139:78c21d98cff6 | 92 | int s_size = 0; |
sb8718 | 139:78c21d98cff6 | 93 | for(int i = 0; i < strlen(buf); i++) { |
sb8718 | 139:78c21d98cff6 | 94 | |
sb8718 | 139:78c21d98cff6 | 95 | sub[s_size] = buf[i]; |
sb8718 | 139:78c21d98cff6 | 96 | s_size++; |
sb8718 | 139:78c21d98cff6 | 97 | |
sb8718 | 139:78c21d98cff6 | 98 | if(s_size % 8 == 7) { |
sb8718 | 139:78c21d98cff6 | 99 | pc.printf("sub-buf\r\n"); |
sb8718 | 139:78c21d98cff6 | 100 | pc.printf("%s\r\n",sub); |
sb8718 | 139:78c21d98cff6 | 101 | pc.printf("\\sub-buf\r\n"); |
sb8718 | 139:78c21d98cff6 | 102 | // send_DMA1_STEAM6_CH4(sub,s_size); |
sb8718 | 139:78c21d98cff6 | 103 | strcpy(sub,""); |
sb8718 | 139:78c21d98cff6 | 104 | s_size = 0; |
sb8718 | 139:78c21d98cff6 | 105 | } |
sb8718 | 139:78c21d98cff6 | 106 | } |
sb8718 | 137:81b5a1672c6a | 107 | |
sb8718 | 139:78c21d98cff6 | 108 | if(s_size > 0) { |
sb8718 | 139:78c21d98cff6 | 109 | pc.printf("sub-buf\r\n"); |
sb8718 | 139:78c21d98cff6 | 110 | pc.printf("%s\r\n",sub); |
sb8718 | 139:78c21d98cff6 | 111 | pc.printf("\\sub-buf\r\n"); |
sb8718 | 139:78c21d98cff6 | 112 | // send_DMA1_STEAM6_CH4(sub,s_size); |
sb8718 | 137:81b5a1672c6a | 113 | } |
sb8718 | 139:78c21d98cff6 | 114 | |
sb8718 | 139:78c21d98cff6 | 115 | free(sub); |
sb8718 | 139:78c21d98cff6 | 116 | free(buf); |
sb8718 | 139:78c21d98cff6 | 117 | free(arr); |
sb8718 | 131:8fb226cc407c | 118 | } |
sb8718 | 139:78c21d98cff6 | 119 | } |
sb8718 | 139:78c21d98cff6 | 120 | void USART2_init (void) |
sb8718 | 139:78c21d98cff6 | 121 | { |
sb8718 | 139:78c21d98cff6 | 122 | RCC->AHB1ENR |= 1; /* enable GPIOA clock */ |
sb8718 | 139:78c21d98cff6 | 123 | RCC->APB1ENR |= 0x20000; /* enable USART2 clock */ |
sb8718 | 139:78c21d98cff6 | 124 | |
sb8718 | 139:78c21d98cff6 | 125 | /* Configure PA2 for USART2_TX */ |
sb8718 | 139:78c21d98cff6 | 126 | GPIOA->AFR[0] &= ~0x0F00; |
sb8718 | 139:78c21d98cff6 | 127 | GPIOA->AFR[0] |= 0x0700; /* alt7 for USART2 */ |
sb8718 | 139:78c21d98cff6 | 128 | GPIOA->MODER &= ~0x0030; |
sb8718 | 139:78c21d98cff6 | 129 | GPIOA->MODER |= 0x0020; /* enable alternate function for PA2 */ |
sb8718 | 139:78c21d98cff6 | 130 | |
sb8718 | 139:78c21d98cff6 | 131 | USART2->BRR = 434; /* 9600 baud @ 16 MHz */ |
sb8718 | 139:78c21d98cff6 | 132 | USART2->CR1 = 0x0008; /* enable Tx, 8-bit data */ |
sb8718 | 139:78c21d98cff6 | 133 | USART2->CR2 = 0x0000; /* 1 stop bit */ |
sb8718 | 139:78c21d98cff6 | 134 | USART2->CR3 = 0x0000; /* no flow control */ |
sb8718 | 139:78c21d98cff6 | 135 | USART2->CR1 |= 0x2000; /* enable USART2 */ |
sb8718 | 139:78c21d98cff6 | 136 | |
sb8718 | 139:78c21d98cff6 | 137 | USART2->SR = ~0x40; /* clear TC flag */ |
sb8718 | 139:78c21d98cff6 | 138 | USART2->CR1 |= 0x0040; /* enable transmit complete interrupt */ |
sb8718 | 139:78c21d98cff6 | 139 | |
sb8718 | 139:78c21d98cff6 | 140 | NVIC_EnableIRQ(USART2_IRQn); /* USART2 interrupt enable at NVIC */ |
sb8718 | 139:78c21d98cff6 | 141 | } |
sb8718 | 139:78c21d98cff6 | 142 | |
sb8718 | 139:78c21d98cff6 | 143 | void DMA1_init(void) |
sb8718 | 139:78c21d98cff6 | 144 | { |
sb8718 | 139:78c21d98cff6 | 145 | RCC->AHB1ENR |= 0x00200000; /* DMA controller clock enable */ |
sb8718 | 139:78c21d98cff6 | 146 | DMA1->HIFCR = 0x003F0000; /* clear all interrupt flags of Stream 6 */ |
sb8718 | 139:78c21d98cff6 | 147 | NVIC_EnableIRQ(DMA1_Stream6_IRQn); /* DMA interrupt enable at NVIC */ |
sb8718 | 139:78c21d98cff6 | 148 | } |
sb8718 | 139:78c21d98cff6 | 149 | |
sb8718 | 139:78c21d98cff6 | 150 | void DMA1_Stream6_setup(unsigned int src, unsigned int dst, int len) |
sb8718 | 139:78c21d98cff6 | 151 | { |
sb8718 | 139:78c21d98cff6 | 152 | DMA1_Stream6->CR &= ~1; /* disable DMA1 Stream 6 */ |
sb8718 | 139:78c21d98cff6 | 153 | while (DMA1_Stream6->CR & 1) {} /* wait until DMA1 Stream 6 is disabled */ |
sb8718 | 139:78c21d98cff6 | 154 | DMA1->HIFCR = 0x003F0000; /* clear all interrupt flags of Stream 6 */ |
sb8718 | 139:78c21d98cff6 | 155 | DMA1_Stream6->PAR = dst; |
sb8718 | 139:78c21d98cff6 | 156 | DMA1_Stream6->M0AR = src; |
sb8718 | 139:78c21d98cff6 | 157 | DMA1_Stream6->NDTR = len; |
sb8718 | 139:78c21d98cff6 | 158 | DMA1_Stream6->CR = 0x08000000; /* USART2_TX on DMA1 Stream6 Channel 4 */ |
sb8718 | 139:78c21d98cff6 | 159 | DMA1_Stream6->CR |= 0x00000440; /* data size byte, mem incr, mem-to-peripheral */ |
sb8718 | 139:78c21d98cff6 | 160 | DMA1_Stream6->CR |= 0x16; /* enable interrupts DMA_IT_TC | DMA_IT_TE | DMA_IT_DME */ |
sb8718 | 139:78c21d98cff6 | 161 | DMA1_Stream6->FCR = 0; /* direct mode, no FIFO */ |
sb8718 | 139:78c21d98cff6 | 162 | DMA1_Stream6->CR |= 1; /* enable DMA1 Stream 6 */ |
sb8718 | 139:78c21d98cff6 | 163 | |
sb8718 | 139:78c21d98cff6 | 164 | USART2->SR &= ~0x0040; /* clear UART transmit complete interrupt flag */ |
sb8718 | 139:78c21d98cff6 | 165 | USART2->CR3 |= 0x80; /* enable USART2 transmitter DMA */ |
sb8718 | 139:78c21d98cff6 | 166 | } |
sb8718 | 139:78c21d98cff6 | 167 | |
sb8718 | 139:78c21d98cff6 | 168 | void DMA1_Stream6_IRQHandler(void) |
sb8718 | 139:78c21d98cff6 | 169 | { |
sb8718 | 139:78c21d98cff6 | 170 | if (DMA1->HISR & 0x000C0000) /* if an error occurred */ |
sb8718 | 139:78c21d98cff6 | 171 | while(1) {} /* substitute this by error handling */ |
sb8718 | 139:78c21d98cff6 | 172 | DMA1->HIFCR = 0x003F0000; /* clear all interrupt flags of Stream 6 */ |
sb8718 | 139:78c21d98cff6 | 173 | DMA1_Stream6->CR &= ~0x10; /* disable DMA1 Stream 6 TCIE */ |
sb8718 | 139:78c21d98cff6 | 174 | } |
sb8718 | 139:78c21d98cff6 | 175 | |
sb8718 | 139:78c21d98cff6 | 176 | void USART2_IRQHandler(void) |
sb8718 | 139:78c21d98cff6 | 177 | { |
sb8718 | 139:78c21d98cff6 | 178 | USART2->SR &= ~0x0040; /* clear transmit complete interrupt flag */ |
sb8718 | 139:78c21d98cff6 | 179 | done = 1; /* set the done flag */ |
sb8718 | 135:03997cc206a4 | 180 | } |