readme etc
This commit is contained in:
@@ -1,78 +1,8 @@
|
||||
# AVR C Boilerplate
|
||||
# Simon Says with Pro Mini
|
||||
|
||||
This is a basic boilerplate for programming AVRs in C.
|
||||
Fun little project that has grown quite more than expected, at least on the hardware side.
|
||||
|
||||
The project aims to make programming Arduinos in C fun by
|
||||
providing support for basic functionality like GPIO and USART,
|
||||
so you can start developing without having the datasheet open
|
||||
all the time.
|
||||
There will be a proper log for this later, with schematics etc.
|
||||
|
||||
It is intended for **ATmega328P** (the chip in Arduinos),
|
||||
but can be easily adapted to other parts.
|
||||
For now, you can have a peek and thank heavens you don't have to understand any of it xD
|
||||
|
||||
## Requirements
|
||||
|
||||
Before you can start coding, you need to install a few software packages:
|
||||
|
||||
- `avrdude` - the flash tool
|
||||
- `avr-gcc` - compiler
|
||||
- `avr-libc` - libc implementation for AVR
|
||||
- `avr-binutils` - utils for manipulating AVR binaries
|
||||
- `make` - to run the Makefile
|
||||
|
||||
There's a good chance you already have `make`, the rest should be in your
|
||||
distribution's repos.
|
||||
|
||||
If you're on Arch:
|
||||
|
||||
```
|
||||
# pacman -S base-devel avr-gcc avr-binutils avr-libc avrdude
|
||||
```
|
||||
|
||||
If you're on Mac, you should be able to pull the stuff with *brew*.
|
||||
|
||||
## Getting started
|
||||
|
||||
The provided `main.c` is a good starting point - it contains some simple demo code.
|
||||
|
||||
You can compile it with `make` and flash with `make flash`.
|
||||
|
||||
### Before you can flash
|
||||
|
||||
First, check that the `avrdude` options in the file are correct for your system - especially
|
||||
the device and speed.
|
||||
|
||||
```ini
|
||||
# AVRDUDE settings
|
||||
PROG_BAUD = 57600
|
||||
PROG_DEV = /dev/ttyUSB0
|
||||
PROG_TYPE = arduino
|
||||
|
||||
# Build the final AVRDUDE arguments
|
||||
PROG_ARGS = -c $(PROG_TYPE) -p $(MCU) -b $(PROG_BAUD) -P $(PROG_DEV)
|
||||
```
|
||||
|
||||
- Adjust `PROG_DEV` to the device your board is connected to. On Linux it's usually
|
||||
`/dev/ttyUSB0`, but it can also be `/dev/ttyACM0` or something else. On Mac, it'll be
|
||||
`/dev/cu.xxx`. On Windows it's some `COMx`.<br>
|
||||
Linux and Mac users can use `ls /dev` to see their devices. Windows users will find
|
||||
this in their Device Manager.
|
||||
- You may also adjust the baudrate (`PROG_BAUD`). Some boards need `115200`.
|
||||
|
||||
**TIP:** You can look what the Arduino IDE is using - it's running avrdude too.
|
||||
|
||||
### Adding new files
|
||||
|
||||
- If you *add a new C file* to the project, add an entry for it's `.o` (object file,
|
||||
created by the compiler before linking) to the `OBJS` list in the Makefile.
|
||||
- Similarly, if you *add a new folder with header files*, add it to `INCL_DIRS`.
|
||||
- In case you need `printf` (or `printf` with floats), enable the appropriate LD_FLAGS
|
||||
in the Makefile (it's well commented). Code size will - obviously - grow quite a bit.
|
||||
|
||||
## Notes
|
||||
|
||||
- The **Arduino UNO** bootloader has a quirk where `Double Speed Asynchronous Mode` for USART
|
||||
is enabled by default, so if you set your baud rate to 9600, you'd really get 19200.<br>
|
||||
We correct this in the `usart_init()` function to keep things consistent and to avoid
|
||||
confusion.<br>
|
||||
*If you wish to turn this on* however, you can do so by using `usart_set_2x(true)`.
|
||||
|
||||
@@ -58,6 +58,8 @@ enum GameState_enum {
|
||||
/** Current game state */
|
||||
enum GameState_enum GameState = STATE_NEW_GAME;
|
||||
|
||||
volatile bool holding_new_game_button = false;
|
||||
|
||||
/** Screen colors */
|
||||
uint32_t screen[4] = {0, 0, 0, 0};
|
||||
const uint32_t brt[4] = {C_BRT1, C_BRT2, C_BRT3, C_BRT4};
|
||||
@@ -125,6 +127,9 @@ suc:
|
||||
/** Enter state - callback for delayed state change */
|
||||
void deferred_enter_state(void *state)
|
||||
{
|
||||
// clear flag that button was held
|
||||
holding_new_game_button = false;
|
||||
|
||||
enter_state((enum GameState_enum) state);
|
||||
}
|
||||
|
||||
@@ -261,8 +266,8 @@ void game_main(void)
|
||||
while (1) {
|
||||
if (GameState == last_state) {
|
||||
if (GameState == STATE_NEW_GAME) {
|
||||
if (cnt == 50) {
|
||||
// clear after 5 secs
|
||||
if (cnt == 20 && !holding_new_game_button) {
|
||||
// clear after 2 secs
|
||||
display_show(SEG_G, SEG_G);
|
||||
}
|
||||
|
||||
@@ -275,9 +280,10 @@ void game_main(void)
|
||||
show_screen();
|
||||
delay_s(2000);
|
||||
pin_down(PIN_PWR_HOLD);
|
||||
while(1); // wait for shutdown
|
||||
}
|
||||
} else {
|
||||
if (cnt > 150) {// 15 secs = stop game.
|
||||
if (cnt > 120) {// 12 secs = stop game.
|
||||
// reset state
|
||||
enter_state(STATE_NEW_GAME);
|
||||
show_screen();
|
||||
@@ -310,6 +316,7 @@ void game_button_handler(uint8_t button, bool press)
|
||||
if (press) {
|
||||
// feedback
|
||||
display_show_number(0); // show 0
|
||||
holding_new_game_button = true;
|
||||
}
|
||||
|
||||
if (!press) { // released
|
||||
|
||||
+6
-4
@@ -11,6 +11,8 @@
|
||||
|
||||
/* Driver code for WS2812B */
|
||||
|
||||
volatile bool ws_no_cli_sei = false;
|
||||
|
||||
void ws_init()
|
||||
{
|
||||
as_output(WS_PIN);
|
||||
@@ -72,27 +74,27 @@ void ws_send_rgb24(rgb24_t rgb)
|
||||
/** Send array of colors */
|
||||
void ws_send_xrgb_array(const xrgb_t rgbs[], const uint8_t length)
|
||||
{
|
||||
cli();
|
||||
if (!ws_no_cli_sei) cli();
|
||||
for (uint8_t i = 0; i < length; i++) {
|
||||
const xrgb_t c = rgbs[i];
|
||||
ws_send_byte(c.g);
|
||||
ws_send_byte(c.r);
|
||||
ws_send_byte(c.b);
|
||||
}
|
||||
sei();
|
||||
if (!ws_no_cli_sei) sei();
|
||||
}
|
||||
|
||||
/** Send array of colors */
|
||||
void ws_send_rgb24_array(const rgb24_t rgbs[], const uint8_t length)
|
||||
{
|
||||
cli();
|
||||
if (!ws_no_cli_sei) cli();
|
||||
for (uint8_t i = 0; i < length; i++) {
|
||||
const rgb24_t c = rgbs[i];
|
||||
ws_send_byte(rgb24_g(c));
|
||||
ws_send_byte(rgb24_r(c));
|
||||
ws_send_byte(rgb24_b(c));
|
||||
}
|
||||
sei();
|
||||
if (!ws_no_cli_sei) sei();
|
||||
}
|
||||
|
||||
//#define ws_send_rgb24_array(rgbs, length) __ws_send_array_proto((rgbs), (length), rgb24)
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
// --- functions for RGB strips ---
|
||||
|
||||
extern volatile bool ws_no_cli_sei;
|
||||
|
||||
/** Initialize OI */
|
||||
void ws_init();
|
||||
|
||||
|
||||
@@ -127,9 +127,26 @@ void task_check_shutdown_btn(void *unused) {
|
||||
if (debo_get_pin(0) // 0 - first
|
||||
&& !booting
|
||||
&& (time_ms - time_pwr_pressed > 1000)) {
|
||||
cli();
|
||||
|
||||
ws_no_cli_sei = true;
|
||||
|
||||
usart_puts("Power OFF\r\n");
|
||||
|
||||
uint32_t zeros[4] = {0,0,0,0};
|
||||
leds_set(zeros);
|
||||
leds_show();
|
||||
|
||||
display_show(0,0);
|
||||
_delay_ms(100);
|
||||
// Wait for user to release
|
||||
while (pin_read(PIN_PWR_KEY));
|
||||
_delay_ms(500);
|
||||
|
||||
// shut down
|
||||
pin_down(PIN_PWR_HOLD);
|
||||
// wait for shutdown
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user