1 | // init uart
|
2 |
|
3 | /*
|
4 | * USART_CHSIZE_9BIT_gc = (0x07<<0)
|
5 | * USART_BAUDCTRL_BSEL_9600 = 621
|
6 | * USART_BAUDCTRL_BSCALE_9600 = -2
|
7 | */
|
8 |
|
9 | void init_usart_slv(void) {
|
10 | PORTC.DIRCLR = PIN6_bm;
|
11 | PORTC.DIRSET = PIN7_bm;
|
12 | PORTC.PIN7CTRL = PORT_INVEN_bm; // TX Inverted I/O data
|
13 |
|
14 | USART_NineBits_InterruptDriver_Initialize(&USART_SLV, &USARTC1, USART_DREINTLVL_LO_gc);
|
15 | USART_Format_Set(USART_SLV.usart, USART_CHSIZE_9BIT_gc, USART_PMODE_DISABLED_gc, false);
|
16 | USART_RxdInterruptLevel_Set(USART_SLV.usart, USART_RXCINTLVL_LO_gc);
|
17 | USART_Baudrate_Set(&USARTC1, USART_BAUDCTRL_BSEL_9600, USART_BAUDCTRL_BSCALE_9600);
|
18 |
|
19 | USART_Rx_Enable(USART_SLV.usart);
|
20 | USART_Tx_Enable(USART_SLV.usart);
|
21 | }
|
22 |
|
23 |
|
24 | // hier das define in der AVR API
|
25 | // siehe optional Seite 296 -> CTRLC – Control register C
|
26 | #define USART_Format_Set(_usart, _charSize, _parityMode, _twoStopBits) \
|
27 | (_usart)->CTRLC = (uint8_t) _charSize | _parityMode | \
|
28 | (_twoStopBits ? USART_SBMODE_bm : 0)
|
29 |
|
30 | // meine ISR
|
31 | ISR(USART_SLV_RXC_vect) {
|
32 | USART_NineBits_RXComplete(&USART_SLV);
|
33 | }
|
34 |
|
35 | // angepasste Funktion aus der AVR API
|
36 | // optional: Suchbegriff "RXB8" (Manual)
|
37 | bool USART_NineBits_RXComplete(USART_NineBits_data_t * usart_data)
|
38 | {
|
39 | USART_NineBits_Buffer_t * bufPtr;
|
40 | bool ans;
|
41 |
|
42 | bufPtr = &usart_data->buffer;
|
43 | /* Advance buffer head. */
|
44 | uint8_t tempRX_Head = (bufPtr->RX_Head + 1) & USART_RX_BUFFER_MASK;
|
45 |
|
46 | /* Check for overflow. */
|
47 | uint8_t tempRX_Tail = bufPtr->RX_Tail;
|
48 | uint16_t data;
|
49 |
|
50 | if(usart_data->usart->STATUS & USART_RXB8_bm) {
|
51 | data = 0x0100 | usart_data->usart->DATA;
|
52 | } else {
|
53 | data = usart_data->usart->DATA;
|
54 | }
|
55 |
|
56 | if (tempRX_Head == tempRX_Tail) {
|
57 | ans = false;
|
58 | }else{
|
59 | ans = true;
|
60 | usart_data->buffer.RX[usart_data->buffer.RX_Head] = data;
|
61 | usart_data->buffer.RX_Head = tempRX_Head;
|
62 | }
|
63 | return ans;
|
64 | }
|
65 |
|
66 | // so lese ich aus
|
67 | bool mdb_receive_9bit(USART_NineBits_data_t *ptr, uint16_t *recv_byte) {
|
68 | if (USART_NineBits_RXBufferData_Available(ptr)) {
|
69 | *recv_byte = USART_NineBits_RXBuffer_GetByte(ptr);
|
70 | return true;
|
71 | }
|
72 | return false;
|
73 | }
|
74 |
|
75 | // hier die obige Funktion
|
76 | bool USART_NineBits_RXBufferData_Available(USART_NineBits_data_t * usart_data)
|
77 | {
|
78 | /* Make copies to make sure that volatile access is specified. */
|
79 | uint8_t tempHead = usart_data->buffer.RX_Head;
|
80 | uint8_t tempTail = usart_data->buffer.RX_Tail;
|
81 |
|
82 | /* There are data left in the buffer unless Head and Tail are equal. */
|
83 | return (tempHead != tempTail);
|
84 | }
|
85 |
|
86 | // hier die obige Funktion
|
87 | uint16_t USART_NineBits_RXBuffer_GetByte(USART_NineBits_data_t * usart_data)
|
88 | {
|
89 | USART_NineBits_Buffer_t * bufPtr;
|
90 | uint16_t ans;
|
91 |
|
92 | bufPtr = &usart_data->buffer;
|
93 | ans = (bufPtr->RX[bufPtr->RX_Tail]);
|
94 |
|
95 | /* Advance buffer tail. */
|
96 | bufPtr->RX_Tail = (bufPtr->RX_Tail + 1) & USART_RX_BUFFER_MASK;
|
97 |
|
98 | return ans;
|
99 | }
|
100 |
|
101 |
|
102 | // hier der Aufrufer in einer Loop
|
103 | uint16_t recv_byte = 0;
|
104 | uint8_t payload = 0;
|
105 | uint8_t modebit = 0;
|
106 | while (mdb_receive_9bit(&USART_SLV, &recv_byte)) {
|
107 | /* hier passiert der sch*ß */
|
108 | // ich überprüfe nur beim ersten empfangenen Bit ob gesetzt
|
109 | if (buf_len == 0) {
|
110 | modebit = recv_byte >> 8;
|
111 | }
|
112 | }
|
113 | /* some magic */
|
114 | buf_len = 0;
|