embox

Форк
0
/
at91_twi.c 
148 строк · 3.4 Кб
1
/**
2
 * @file
3
 * @brief TWI communication for Lego AVR
4
 *
5
 * @date 26.09.10
6
 * @author Anton Kozlov
7
 * @author Fedor Burdun
8
 */
9

10
#include <stdint.h>
11
#include <embox/unit.h>
12
#include <kernel/panic.h>
13
#include <hal/reg.h>
14
#include <hal/system.h>
15
#include <drivers/at91sam7s256.h>
16

17
#include <drivers/twi.h>
18

19
EMBOX_UNIT_INIT(twi_init);
20

21
#define   TWICLK           400000L //TODO move to global config -- special to system where runs
22
#define   CLDIV            (((SYS_CLOCK/TWICLK)/2)-3)
23

24
static uint32_t twi_pending;
25
static uint8_t *twi_ptr;
26
static uint32_t twi_mask;
27

28
#define BUF_SIZE 128
29
static uint8_t out_buff[BUF_SIZE];
30

31
static void systick_wait_ns(uint32_t ns) {
32
	uint32_t x = (ns >> 7) + 1;
33
	while (x) {
34
		x--;
35
	}
36
}
37

38
static void twi_reset(void) {
39
	uint32_t clocks = 9;
40

41
	REG_STORE(AT91C_TWI_IDR, ~0);
42

43
	REG_STORE(AT91C_PMC_PCER, (1 << AT91C_ID_PIOA) |  /* Need PIO too */
44
			(1 << AT91C_ID_TWI));    /* TWI clock domain */
45

46
	/* MAGIC Set up pin as an IO pin for clocking till clean */
47
	/* Why we need to clock? */
48
	REG_STORE(AT91C_PIOA_MDER, AT91C_PA3_TWD | AT91C_PA4_TWCK);
49
	REG_STORE(AT91C_PIOA_PER, AT91C_PA3_TWD | AT91C_PA4_TWCK);
50
	REG_STORE(AT91C_PIOA_ODR, AT91C_PA3_TWD);
51
	REG_STORE(AT91C_PIOA_OER, AT91C_PA4_TWCK);
52

53
	while (clocks > 0 && !(REG_LOAD(AT91C_PIOA_PDSR) & AT91C_PA3_TWD)) {
54
		REG_STORE(AT91C_PIOA_CODR, AT91C_PA4_TWCK);
55
		systick_wait_ns(1500);
56
		REG_STORE(AT91C_PIOA_SODR, AT91C_PA4_TWCK);
57
		systick_wait_ns(1500);
58
		clocks--;
59
	}
60

61
	REG_STORE(AT91C_PIOA_PDR, AT91C_PA3_TWD | AT91C_PA4_TWCK);
62
	REG_STORE(AT91C_PIOA_ASR, AT91C_PA3_TWD | AT91C_PA4_TWCK);
63
	/* MAGIC END */
64

65
	/* Disable & reset */
66
	REG_STORE(AT91C_TWI_CR, AT91C_TWI_SWRST | AT91C_TWI_MSDIS);
67

68
	/* Set for 400kHz */
69
	REG_STORE(AT91C_TWI_CWGR, ((CLDIV << 8) | CLDIV));
70
	/* Enable as master */
71
	REG_STORE(AT91C_TWI_CR, AT91C_TWI_MSEN);
72
	//*AT91C_TWI_IER = AT91C_TWI_NACK;
73
	twi_mask = 0;
74
}
75

76
static int twi_init(void) {
77
	twi_reset();
78
	return 0;
79
}
80

81
void twi_write(uint32_t dev_addr, const uint8_t *data, uint32_t nBytes) {
82
	twi_ptr = (uint8_t *) data;
83
	twi_pending = nBytes;
84

85
	REG_STORE(AT91C_TWI_MMR, AT91C_TWI_IADRSZ_NO | ((dev_addr & 0x7f) << 16));
86

87
	REG_STORE(AT91C_TWI_THR, *twi_ptr++);
88
	twi_pending--;
89

90
	while (twi_pending > 0) {
91
		while (!(REG_LOAD(AT91C_TWI_SR) & AT91C_TWI_TXRDY));
92
		REG_STORE(AT91C_TWI_THR, *twi_ptr++);
93
		twi_pending--;
94
	}
95

96
	while (!(REG_LOAD(AT91C_TWI_SR) & AT91C_TWI_TXCOMP));
97
}
98

99
void twi_send(uint32_t dev_addr, const uint8_t *data, uint32_t count) {
100
	const uint8_t *sptr = data;
101
	uint8_t *dptr = out_buff;
102
	uint8_t checkbyte = 0;
103
	uint32_t left_count = count;
104
#if 0
105
	if (count >= BUF_SIZE) {
106
		panic("Sending to AVR abnormal long data\n");
107
	}
108
#endif
109
	while (left_count-- > 0) {
110
		checkbyte += *sptr;
111
		*dptr++ = *sptr++;
112
	}
113

114
	*dptr = ~checkbyte;
115
	twi_write(dev_addr, out_buff, count + 1);
116
}
117

118
int twi_receive(uint32_t dev_addr, uint8_t *data, uint32_t count) {
119
	uint8_t *ptr = data;
120
	uint8_t checkbyte = 0;
121

122
	REG_STORE(AT91C_TWI_MMR, AT91C_TWI_IADRSZ_NO |
123
			AT91C_TWI_MREAD | ((dev_addr & 0x7f) << 16));
124
	REG_STORE(AT91C_TWI_CR, AT91C_TWI_START);
125

126
	while (count-- > 1) {
127
		while (!(REG_LOAD(AT91C_TWI_SR) & AT91C_TWI_RXRDY));
128

129
		*ptr = REG_LOAD(AT91C_TWI_RHR);
130
		checkbyte += *ptr;
131
		ptr++;
132
	}
133

134
	REG_STORE(AT91C_TWI_CR, AT91C_TWI_STOP);
135

136
	while (!(REG_LOAD(AT91C_TWI_SR) & AT91C_TWI_RXRDY)) {
137

138
	}
139

140
	*ptr = REG_LOAD(AT91C_TWI_RHR);
141
	checkbyte += *ptr;
142

143
	while (!(REG_LOAD(AT91C_TWI_SR) & AT91C_TWI_TXCOMP)) {
144

145
	}
146

147
	return ((checkbyte == 0xff) ? 1 : 0);
148
}
149

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.