Maixduino icon indicating copy to clipboard operation
Maixduino copied to clipboard

Using MD_PIN_MAP removes the ability to control K210 Chip IO Pins for SPI etc...

Open TheMindVirus opened this issue 5 years ago • 2 comments

I have a project that requires advanced usage of the K210 IO pins on a Sipeed Maixduino board. However, the default digitalWrite, pinMode etc. methods use an array called MD_PIN_MAP for pin mapping. This is restrictive and doesn't allow full use of the K210 IO pins.

Provided that you know what you are doing, here is my fix:

void pinModeIO(uint8_t pin, uint8_t mode)
{
  fpioa_function_t function = (fpioa_function_t)(FUNC_GPIOHS0 + pin);
  fpioa_set_function(pin, function);
  gpiohs_set_drive_mode(pin, (gpio_drive_mode_t)mode);
}
#define digitalWriteIO(PIN, VALUE)   gpiohs_set_pin(PIN, (gpio_pin_value_t)VALUE)
#define digitalReadIO(PIN)           gpiohs_get_pin(PIN)

I am finding myself having to rewrite the SPI and UART library to accommodate this change too.

TheMindVirus avatar Aug 23 '19 12:08 TheMindVirus

I have Serial working between the K210 and ESP32 using a custom class I wrote based on UARTClass: (Please note, to update the ESP32 firmware, the reset button must be held down during flashing)

Maix_UART.h

#ifndef MAIX_UART_H
#define MAIX_UART_H

class UART
{
public:
  UART(uint8_t rx = 6, uint8_t tx = 7,
       fpioa_function_t rx_func = FUNC_UART1_RX,
       fpioa_function_t tx_func = FUNC_UART1_TX,
       uart_bitwidth_t width = UART_BITWIDTH_8BIT,
       uart_stopbit_t stopbit = UART_STOP_1,
       uart_parity_t parity = UART_PARITY_NONE)
  {
    this->rx = rx;
    this->tx = tx;
    this->rx_func = rx_func;
    this->tx_func = tx_func;
    this->width = width;
    this->stopbit = stopbit;
    this->parity = parity;
  }
  
  void begin(uint32_t baud = 115200)
  {
    this->baud = baud;
    fpioa_set_function(rx, this->rx_func);
    fpioa_set_function(tx, this->tx_func);
    uart_init(this->handle);
    uart_configure(this->handle, this->baud, this->width, this->stopbit, this->parity);
    this->buffer = new RingBuffer();
    uart_set_receive_trigger(this->handle, UART_RECEIVE_FIFO_1);
    uart_irq_register(this->handle, UART_RECEIVE, this->receiveCB, this, 5);
    sysctl_enable_irq();
  }

  static int receiveCB(void* ctx)
  {
    char tmp = '\0';
    UART* uart = (UART*)ctx;
    while(uart_receive_data(uart->handle, &tmp, 1)) { uart->buffer->store_char(tmp); }
    return 0;
  }

  int available()
  {
    return this->buffer->available();
  }

  char read()
  {
    if(this->available()) { return this->buffer->read_char(); }
    return -1;
  }
  
  void print(char* data, int len = -1)
  {
    if(len < 0) len = strlen(data);
    for(int i = 0; i < len; ++i)
    {
      while(uart[this->handle]->LSR & (1u << 5)) { }
      uart[this->handle]->THR = data[i];
    }
  }

  void println(char* data, int len = -1)
  {
    char newline[] = "\n";
    this->print(data, len);
    this->print(newline, strlen(newline));
  }
  
private:
  uint32_t baud;
  uint8_t rx;
  uint8_t tx;
  fpioa_function_t rx_func;
  fpioa_function_t tx_func;
  uart_bitwidth_t width;
  uart_stopbit_t stopbit;
  uart_parity_t parity;
  uart_device_number_t handle;
  RingBuffer* buffer;
};

#endif//MAIX_UART_H

K210_Usage.ino

UART ESP32; //ESP32(6, 7);

void setup()
{
  ESP32.begin(115200);

  int nBytes = 0;
  char buffer[255] = "";
  char message[] = "Hello ESP32";
  while(1)
  {
    ESP32.println(message);
    nBytes = ESP32.available();
    if(nBytes > 0)
    {
      for(int i = 0; i < nBytes; ++i) { buffer[i] = (char)ESP32.read(); }
      buffer[nBytes] = '\0';
      Serial.println(buffer);
    }
    delay(1000);
  }
}

void loop() { }

ESP32_Usage.ino

void setup()
{
  Serial.begin(115200);

  int nBytes = 0;
  char buffer[255] = "";
  char message[] = "Hello ESP32";
  char response[] = "Hello K210";
  while(1)
  {
    nBytes = Serial.available();
    if(nBytes > 0)
    {
      for(int i = 0; i < nBytes; ++i) { buffer[i] = (char)Serial.read(); }
      buffer[nBytes] = '\0';
      Serial.print(buffer);
      if(strncmp(buffer, message, strlen(message)) == 0) { Serial.println(response); }
    }
    delay(500);
  }
}

void loop() { }

TheMindVirus avatar Aug 23 '19 15:08 TheMindVirus

For printing floats, the print() method above may need to be modified to use sprintf() using preprocessor macros. This will make it more like the Arduino standard printer.

TheMindVirus avatar Aug 23 '19 16:08 TheMindVirus