diff options
Diffstat (limited to 'firmware/target/arm/as3525/dbop-as3525.c')
-rw-r--r-- | firmware/target/arm/as3525/dbop-as3525.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/firmware/target/arm/as3525/dbop-as3525.c b/firmware/target/arm/as3525/dbop-as3525.c index 938eee2fb1..b54ad17a6c 100644 --- a/firmware/target/arm/as3525/dbop-as3525.c +++ b/firmware/target/arm/as3525/dbop-as3525.c | |||
@@ -20,6 +20,7 @@ | |||
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #include "config.h" | 22 | #include "config.h" |
23 | #include <inttypes.h> | ||
23 | #include "as3525.h" | 24 | #include "as3525.h" |
24 | #include "dbop-as3525.h" | 25 | #include "dbop-as3525.h" |
25 | 26 | ||
@@ -75,3 +76,50 @@ unsigned short dbop_debug(void) | |||
75 | { | 76 | { |
76 | return dbop_input_value; | 77 | return dbop_input_value; |
77 | } | 78 | } |
79 | |||
80 | static inline void dbop_set_mode(int mode) | ||
81 | { | ||
82 | int delay = 10; | ||
83 | if (mode == 32 && (!(DBOP_CTRL & (1<<13|1<<14)))) | ||
84 | DBOP_CTRL |= (1<<13|1<<14); | ||
85 | else if (mode == 16 && (DBOP_CTRL & (1<<13|1<<14))) | ||
86 | DBOP_CTRL &= ~(1<<14|1<<13); | ||
87 | else | ||
88 | return; | ||
89 | while(delay--) asm volatile("nop"); | ||
90 | } | ||
91 | |||
92 | void dbop_write_data(const int16_t* p_bytes, int count) | ||
93 | { | ||
94 | |||
95 | const int32_t *data; | ||
96 | if ((intptr_t)p_bytes & 0x3 || count == 1) | ||
97 | { /* need to do a single 16bit write beforehand if the address is | ||
98 | * not word aligned or count is 1, switch to 16bit mode if needed */ | ||
99 | dbop_set_mode(16); | ||
100 | DBOP_DOUT16 = *p_bytes++; | ||
101 | if (!(--count)) | ||
102 | return; | ||
103 | } | ||
104 | /* from here, 32bit transfers are save | ||
105 | * set it to transfer 4*(outputwidth) units at a time, | ||
106 | * if bit 12 is set it only does 2 halfwords though (we never set it) | ||
107 | * switch to 32bit output if needed */ | ||
108 | dbop_set_mode(32); | ||
109 | data = (int32_t*)p_bytes; | ||
110 | while (count > 1) | ||
111 | { | ||
112 | DBOP_DOUT32 = *data++; | ||
113 | count -= 2; | ||
114 | |||
115 | /* Wait if push fifo is full */ | ||
116 | while ((DBOP_STAT & (1<<6)) != 0); | ||
117 | } | ||
118 | /* While push fifo is not empty */ | ||
119 | while ((DBOP_STAT & (1<<10)) == 0); | ||
120 | |||
121 | /* due to the 32bit alignment requirement or uneven count, | ||
122 | * we possibly need to do a 16bit transfer at the end also */ | ||
123 | if (count > 0) | ||
124 | dbop_write_data((int16_t*)data, 1); | ||
125 | } | ||