Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
TheMindVirus opened this issue Aug 23, 2019 · 2 comments

Comments

@TheMindVirus
Copy link

TheMindVirus commented Aug 23, 2019

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
Copy link
Author

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
Copy link
Author

TheMindVirus commented Aug 23, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant