Skip to content

Instantly share code, notes, and snippets.

@christakahashi
Last active December 17, 2020 08:45
Show Gist options
  • Save christakahashi/1e19c7dba4caca2bb04028c88504ea7f to your computer and use it in GitHub Desktop.
Save christakahashi/1e19c7dba4caca2bb04028c88504ea7f to your computer and use it in GitHub Desktop.
//A SUPER SIMPLE soft UART TX for any AVR(ATmega/AT90/ATtiny).
// Tested on an ATmega16M1 @ 8mhz.
// 46 bytes of code space.
// 57600 baud at F_OSC 8mhz
// The baud rate will scale with CPU frequency so be careful.
//
// For basic debug only.
// No guarentee this will work.
//
// By: Chris Takahashi 2020
// Licence CC0 (public domain):
// To the extent possible under law, Chris Takahashi
// has waived all copyright and related or neighboring
// rights to this work (soft_uart_tx_only.c).
// This work is published from: United States.
#define SS_DDR_PORT DDRB
#define SS_PORT PORTB
#define SS_PIN 2
void init_suart(){
SS_DDR_PORT |= 1<<SS_PIN;
}
void suart_tx(uint8_t c) {
//139 clocks at 8mhz is (close to) 57600 bps =17.3611us
//START BIT
SS_PORT &=~(1<<SS_PIN);
__builtin_avr_delay_cycles(139-1);
for(uint8_t x=8;x>0;x--) {
if (c&1) {
SS_PORT |=1<<SS_PIN; //sbi = 1 cycle
} else {
SS_PORT &=~(1<<SS_PIN); //cbi = 1 cycle
//it's shaky which branch the nops go.
// it depends on if the compiler uses SBIC or SBIS
// check the listing or try sending 'U'(b'01010101)
// and check with a scope
_NOP();
_NOP();
_NOP();
}
c = c>>1; // 1 inst
//not going to lie,
// I tweaked the delays with a scope until it was right.
__builtin_avr_delay_cycles(139-6-4);
}
//stop bit
SS_PORT |= 1<<SS_PIN;
//You can delete the line below if you can guarentee
// that you won't call this function again for another 140 cycles.
__builtin_avr_delay_cycles(139 );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment