modm-io / modm

modm: a C++23 library generator for AVR and ARM Cortex-M devices
https://modm.io
Mozilla Public License 2.0
733 stars 132 forks source link

UART on ATmega8 #206

Closed Sh4rK closed 5 years ago

Sh4rK commented 5 years ago

I'm trying to write a program for an ATmega8 that needs UART.

Based on the AVR examples I put together this project.xml:

<library>
  <options>
    <option name="modm:target">atmega8</option>
    <option name="modm:platform:clock:f_cpu">8000000</option>
    <option name="modm:io:with_printf">True</option>
    <option name="modm:build:avrdude.programmer">avrisp2</option>
  </options>
  <modules>
    <module>modm:architecture:interrupt</module>
    <module>modm:driver:mcp2515</module>
    <module>modm:platform:clock</module>
    <module>modm:platform:core</module>
    <module>modm:platform:gpio</module>
    <module>modm:platform:spi</module>
    <module>modm:platform:uart:0</module>
    <module>modm:processing:timer</module>
    <module>modm:build:scons</module>
  </modules>
</library>

When I run lbuild -r ..\modm\repo.lb build I get this output:

Recomputing device cache...

ERROR: Cannot resolve 'modm:platform:uart:0'

I tried replacing modm:platform:uart:0 with modm:platform:uart, modm:platform:uart:1, but nothing seems to work. Does this mean that the UART is not supported on the mega8 yet?

salkinium commented 5 years ago
 $ lbuild -r repo.lb -D :target=atmega8 discover -t :platform
Module(modm:platform)   Platform HAL
├── Module(modm:platform:1-wire.bitbang)   Software 1-Wire
├── Module(modm:platform:adc)   Analog-to-Digital Converter (ADC)
├── Module(modm:platform:can.common)   CAN Common
├── Module(modm:platform:clock)   System Clock
│   ╰── NumericOption(f_cpu) = REQUIRED in [1 ... 32000000]   CPU clock frequency
├── Module(modm:platform:core)   AVR Core
│   ├── EnumerationOption(ram_block_length) = 16 in [2, 4, 8, 16, 32, 64]
│   ╰── NumericOption(ram_length) = 1024 in [64 .. 1024 .. 32768]
├── Module(modm:platform:gpio)   General Purpose I/O (GPIO)
├── Module(modm:platform:gpio.common)   GPIO Common
├── Module(modm:platform:i2c)   Inter-Integrated Circuit (I²C)
├── Module(modm:platform:i2c.bitbang)   Software Inter-Integrated Circuit (I²C)
├── Module(modm:platform:spi)   Serial Peripheral Interface (SPI)
│   ╰── BooleanOption(busywait) = False in [True, False]
╰── Module(modm:platform:spi.bitbang)   Software Serial Peripheral Interface (SPI)

Hm… why isn't there a UART module?

salkinium commented 5 years ago

There is no "instance" in the driver in modm-devices:

    driver = device.get_driver("usart")
    if "instance" in driver:
        for instance in listify(driver["instance"]):
            module.add_submodule(Instance(int(instance)))
    else:
        return False

=> From here

<driver name="usart" type="avr"/>

=> From here

salkinium commented 5 years ago

Looking at the ATmega8 datasheet, modm-devices is correct, the instance is called just USART, not USART0. So the driver needs to be adapted to work with a None or "" (empty string) instance.

salkinium commented 5 years ago

The SPI driver does something similar already, by building in modm:platform:spi directly instead of a submodule. I'm not sure why I didn't port this from xpcc the same way: https://github.com/modm-io/modm/blob/develop/src/modm/platform/spi/at90_tiny_mega/module.lb#L79-L92