| 188 | #if defined(UBRR0) |
| 189 | template <u8 _DATA_PIN, u8 _CLOCK_PIN, u32 _SPI_CLOCK_DIVIDER> |
| 190 | class AVRUSART0SPIOutput { |
| 191 | Selectable *mPSelect; |
| 192 | |
| 193 | public: |
| 194 | AVRUSART0SPIOutput() { mPSelect = nullptr; } |
| 195 | AVRUSART0SPIOutput(Selectable *pSelect) { mPSelect = pSelect; } |
| 196 | void setSelect(Selectable *pSelect) { mPSelect = pSelect; } |
| 197 | |
| 198 | void init() FL_NOEXCEPT { |
| 199 | UBRR0 = 0; |
| 200 | |
| 201 | /* Set MSPI mode of operation and SPI data mode 0. */ |
| 202 | UCSR0C = (1<<UMSEL01)|(1<<UMSEL00)/*|(0<<UCPHA0)*/|(0<<UCPOL0); |
| 203 | /* Enable receiver and transmitter. */ |
| 204 | UCSR0B = (1<<RXEN0)|(1<<TXEN0); |
| 205 | |
| 206 | FastPin<_CLOCK_PIN>::setOutput(); |
| 207 | FastPin<_DATA_PIN>::setOutput(); |
| 208 | |
| 209 | // must be done last, see page 206 |
| 210 | setSPIRate(); |
| 211 | } |
| 212 | |
| 213 | void setSPIRate() FL_NOEXCEPT { |
| 214 | if(_SPI_CLOCK_DIVIDER > 2) { |
| 215 | UBRR0 = (_SPI_CLOCK_DIVIDER/2)-1; |
| 216 | } else { |
| 217 | UBRR0 = 0; |
| 218 | } |
| 219 | } |
| 220 | |
| 221 | static void stop() FL_NOEXCEPT { |
| 222 | // TODO: stop the uart spi output |
| 223 | } |
| 224 | |
| 225 | static bool shouldWait(bool wait = false) FL_NOEXCEPT __attribute__((always_inline)) { |
| 226 | static bool sWait=false; |
| 227 | if(sWait) { |
| 228 | sWait = wait; return true; |
| 229 | } else { |
| 230 | sWait = wait; return false; |
| 231 | } |
| 232 | // return true; |
| 233 | } |
| 234 | static void wait() FL_NOEXCEPT __attribute__((always_inline)) { |
| 235 | if(shouldWait()) { |
| 236 | while(!(UCSR0A & (1<<UDRE0))); |
| 237 | } |
| 238 | } |
| 239 | static void waitFully() __attribute__((always_inline)) { wait(); } |
| 240 | |
| 241 | static void writeWord(u16 w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); } |
| 242 | |
| 243 | static void writeByte(u8 b) __attribute__((always_inline)) { wait(); UDR0=b; shouldWait(true); } |
| 244 | static void writeBytePostWait(u8 b) __attribute__((always_inline)) { UDR0=b; shouldWait(true); wait(); } |
| 245 | static void writeByteNoWait(u8 b) __attribute__((always_inline)) { UDR0=b; shouldWait(true); } |
| 246 | |
| 247 | |